简体   繁体   English

在Enum值中使用特殊字符

[英]Using special characters in Enum value

I'm refactoring an ASP.NET MVC application that contains a Grid that uses remote filtering, sorting and pagination, it currently uses a string to pass the comparison operator that should be applied, I'd like to change that into an Enum: 我正在重构一个ASP.NET MVC应用程序,该应用程序包含一个使用远程过滤,排序和分页的Grid,它当前使用一个字符串来传递应该应用的比较运算符,我想将其更改为Enum:

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 View: 在视图中:

//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); 

My problem is that this results in an exception (= is not a valid value for EnumComparisonOperators.) as the calling grid component uses the string "=" for the "equals" operation and the controller doesn't parse that automatically, so my question is: 我的问题是,这导致异常(=对于EnumComparisonOperators来说不是有效值。),因为调用网格组件将字符串“ =”用于“等于”操作,并且控制器不会自动解析该字符串,所以我的问题是是:

Is there a way for me to change/decorate/configure the Enum, so that "=" is recognized by the controller as a valid value as opposed to "Equals". 有没有一种方法可以更改/修饰/配置Enum,以便控制器将“ =”识别为有效值,而不是“等于”。

So in essence I'm trying to achieve the behavior I would get if = were the name of my enum's value, but = is a special character so I used Equals and am looking for configuration that would make it behave like = , that means, parsing and serialization should use = 因此,从本质上讲,我试图实现如果=是我的枚举值的名称,但是=是一个特殊字符,所以我将使用Equals并寻找使它的行为类似于= ,这意味着,解析和序列化应使用=

The exception " = is not a valid value for EnumComparisonOperators " indicates that you're passing string which doesn't recognized as proper enum value (which contains integer indexes). 异常“ =对EnumComparisonOperators无效 ”表示您正在传递的字符串未被识别为正确的枚举值(包含整数索引)。 You can keep <Description> attributes for each enum members (because you can't use operator symbols as enum member like EnumComparisonOperators.= or EnumComparisonOperators.<= ), but it's necessary to write your own function to set enum member value from operator key in JSON using reflection like example below (adapted from this reference ): 您可以为每个枚举成员保留<Description>属性(因为不能将运算符作为EnumComparisonOperators.=EnumComparisonOperators.<=枚举成员使用),但是必须编写自己的函数以通过operator键设置枚举成员值在JSON中使用下面的示例进行反射(改编自此参考资料 ):

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

Afterwards, call the function above inside controller action (depending on your current implementation, these codes are subject to change): 然后,在控制器动作内部调用上面的函数(根据您当前的实现,这些代码可能会更改):

Model 模型

Public Class FilterModel

    Public Property operator As String

    ' other properties
End Class

Controller 调节器

<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

See also this fiddle for another usage example. 另请参见此小提琴以获得另一个用法示例。

Note: Another available alternative is using EnumMemberAttribute like <EnumMember(Value := "=")> for every enum members and create a function to read that value as described in this issue . 注意:另一个可用的替代方法是为每个枚举成员使用EnumMemberAttribute类的<EnumMember(Value := "=")> ,并创建一个函数来读取该值,如本期中所述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM