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