【问题标题】:Using special characters in Enum value在枚举值中使用特殊字符
【发布时间】:2018-09-10 15:25:24
【问题描述】:

我正在重构一个 ASP.NET MVC 应用程序,其中包含一个使用远程过滤、排序和分页的 Grid,它当前使用一个字符串来传递应该应用的比较运算符,我想将其更改为枚举:

Public Class MyController
    Inherits Controller
    Public Function GetOrders(filterModels As List(Of FilterModel)) As JsonResult
        'A member of FilterModel is of type EnumComparisonOperators here
        ...
    End Function
End Class

Public Enum EnumComparisonOperators
    <Description("=")>
    Equals = 0
    <Description("<>")>
    NotEquals = 1
    <Description("<=")>
    LessThanOrEquals = 2
    <Description(">")>
    GreaterThan = 3
    <Description(">=")>
    GreaterThanOrEquals = 4
End Enum

在视图中:

//In the real code, my ajax call is in a callback from a third party
//component that just passes these loadOptions
var loadOptions = { 
    filterModel: { 
        operator: "=" //Replacing this string with "Equals" causes the code to work
                      //But my application logic needs a "=" sign, so I'd like to avoid 
                      //converting back and forth
    } 
};

//The exception gets thrown the server when it receives this post call
$.post("/My/GetOrders", loadOptions); 

我的问题是这会导致异常(= 不是 EnumComparisonOperators 的有效值。)因为调用网格组件使用字符串“=”进行“等于”操作,并且控制器不会自动解析,所以我的问题是:

有没有办法让我更改/装饰/配置枚举,以便控制器将“=”识别为有效值,而不是“等于”。

所以本质上我正在尝试实现如果= 是我的枚举值的名称,但 = 是一个特殊字符,所以我使用了Equals 并正在寻找能够实现它的配置表现得像=,也就是说,解析和序列化应该使用=

【问题讨论】:

  • 我无法理解问题:c
  • 编辑了问题,但 tl。博士,我希望我的枚举值被命名为=,而不是Equals
  • 如果问题是网格组件向这个控制器方法发送了=,那么您只需将FilterModel类中的比较运算符属性更改为字符串而不是枚举.然后您的控制器方法可以在处理请求之前解析字符串以找到匹配的枚举值。控制器甚至可以使用反射来查找与Description 属性中的匹配值的枚举值。
  • 如何显示引发异常“= 不是 EnumComparisonOperators 的有效值”的代码? language rules 不允许使用 = 作为标识符名称。
  • @TnTinMn ajax调用控制器时抛出异常$.post("/My/GetOrders", loadOptions);

标签: ajax asp.net-mvc vb.net


【解决方案1】:

异常“= is not a valid value for EnumComparisonOperators”表示您传递的字符串不能识别为正确的枚举值(包含整数索引)。您可以为每个枚举成员保留&lt;Description&gt; 属性(因为您不能使用运算符符号作为枚举成员,如EnumComparisonOperators.=EnumComparisonOperators.&lt;=),但必须编写自己的函数来设置来自operator 的枚举成员值使用反射键入 JSON,如下例所示(改编自 this reference):

Public Function GetDescription(Of T)(ByVal value As T) As String
    Dim field As FieldInfo = value.[GetType]().GetField(value.ToString())
    Dim attributes As DescriptionAttribute() = CType(field.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())

    If attributes IsNot Nothing AndAlso attributes.Length > 0 Then
        Return attributes(0).Description
    Else
        Return value.ToString()
    End If
End Function

Public Function GetEnumValueFromOperator(Of T)(ByVal op As String) As T
    Dim array As Array = [Enum].GetValues(GetType(T))
    Dim list = New List(Of T)(array.Length)

    For i As Integer = 0 To array.Length - 1
        list.Add(CType(array.GetValue(i), T))
    Next

    Dim dic = list.[Select](Function(x) New With {
        .Value = v,
        .Description = GetDescription(x)
    }).ToDictionary(Function(s) s.Description, Function(s) s.Value)
    Return dic(op)
End Function

然后,在控制器动作中调用上面的函数(取决于您当前的实现,这些代码可能会发生变化):

型号

Public Class FilterModel

    Public Property operator As String

    ' other properties
End Class

控制器

<HttpPost()>
Public Function GetOrders(filterModels As List(Of FilterModel)) As JsonResult
    ' check against null or zero length (filterModels.Count = 0) first

    For Each fm As FilterModel In filterModels
        Dim selectedOperator = GetEnumValueFromOperator(Of EnumComparisonOperators)(fm.operator)

        Select Case selectedOperator
            Case 0 ' Equals
               ' do something
        End Select

    Next

    ' other stuff
    Return Json(...)
End Function

另请参阅this fiddle 了解另一个用法示例。

注意:另一种可用的替代方法是对每个枚举成员使用EnumMemberAttribute,例如&lt;EnumMember(Value := "=")&gt;,并创建一个函数来读取该值,如this issue 中所述。

【讨论】:

  • 我无法从控制器操作中调用任何函数,因为在调用控制器之前引发了异常,&lt;EnumMember(Value := "=")&gt;&lt;JsonConverter(GetType(StringEnumConverter))&gt; 似乎正是我想要的,但不能让它工作呢。 (添加它们对我没有影响)
猜你喜欢
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多