Использование специальных символов в значении Enum - PullRequest
0 голосов
/ 10 сентября 2018

Я выполняю рефакторинг приложения 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 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.), Так как вызывающий компонент сетки использует строку "=" для операции "равно", и контроллер не анализирует это автоматически, поэтому мой вопрос:

Есть ли способ для меня изменить / декорировать / настроить Enum, чтобы "=" распознавался контроллером как действительное значение, а не "Равно".

Так что, по сути, я пытаюсь добиться поведения, которое получилось бы, если бы = было именем значения моего перечисления, но = это специальный символ, поэтому я использовал Equals и ищу конфигурацию, которая бы его сделала вести себя как =, это означает, что при разборе и сериализации следует использовать =

1 Ответ

0 голосов
/ 12 сентября 2018

Исключение " = не является допустимым значением для EnumComparisonOperators " указывает, что вы передаете строку, которая не распознается как правильное значение перечисления (которая содержит целочисленные индексы).Вы можете оставить атрибуты <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

После этого вызовите функцию выше внутри действия контроллера (в зависимости от текущей реализации эти коды являются предметомизменить):

Модель

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

См. также эту скрипку для другого примера использования.

Примечание: Другой доступной альтернативой является использование EnumMemberAttribute подобно <EnumMember(Value := "=")> для каждого члена перечисления и создание функции для чтения этого значения, как описано в этот выпуск .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...