在Enum值中使用特殊字符

时间:2018-09-10 15:25:24

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

我正在重构一个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并正在寻找配置这将使其表现得像=,这意味着解析和序列化应使用=

1 个答案:

答案 0 :(得分:1)

异常“ =不是EnumComparisonOperators的有效值”表示您正在传递的字符串未被识别为正确的枚举值(包含整数索引)。您可以为每个枚举成员保留<Description>属性(因为您不能将运算符作为像EnumComparisonOperators.=EnumComparisonOperators.<=这样的枚举成员使用),但是必须编写自己的函数来设置枚举JSON中operator键的成员值,使用下面的示例进行反射(改编自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之类的<EnumMember(Value := "=")>,如this issue中所述,并创建一个函数读取该值。 / p>