Лучшая практика для передачи параметров enum в Web API

У меня есть проект RESTful Web API, и у меня есть 2 разных сценария Enum, которые я не уверен в лучшей практике.

Сценарий 1: Простой параметр Enum Param

Для моего метода API требуется параметр, называемый ruleType, при этом допустимыми значениями являются EmailAddress и IPAddress. Мое перечисление в проекте веб-API выглядит следующим образом:

public enum RuleType
{
    None = 0,
    EmailAddress = 1,
    IPAddress = 2
}

Мой вопрос для этого сценария: должен ли я использовать ?ruleType=EmailAddress в моем запросе API (который автоматически связывает это значение с моим свойством RuleType в методе API)? Если да, то как лучше всего проверить, что параметр RuleType отправлен, является допустимым значением Enule RuleType?

Сценарий 2: множественные значения перечисления для одного параметра

Мой API-метод имеет необязательный параметр fields, который позволяет указать любые дополнительные данные, которые должны быть возвращены. Eg &fields=ruleOwner,rule. Это вернет эти 2 дополнительных бита данных в ответ.

У меня есть перечисление в проекте веб-API, которое относится к каждому возможному field которое может быть запрошено, и в настоящее время я разделяю запятые поля param, затем перебираю каждое строковое представление этого перечисления, анализируя его на эквивалентное перечисление, в результате получится список значений Enum, которые я могу затем использовать в моем API для получения соответствующих данных.

Это Enum:

public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    etc.
}

Что было бы лучше всего здесь? Я искал побитовые перечисления, поэтому в запросе API отправляется одно значение, которое приводило к любой комбинации fields но не знало, будет ли это хорошо работать с веб-API, или если в целом есть лучший способ сделать это?

Ответы

Ответ 1

лучше всего сделать URI "удобочитаемым человеком". поэтому я также могу понять, почему вы используете Enum в качестве строки. Но, как сказал Христо Колев, вам нужно написать собственный образец Binder.

В полях я думаю, вы не должны использовать комбинацию перечислений. потому что это трудно понять. возможно, вы можете создать комбинацию enum как запись перечисления

public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    RuleAndRuleOwner = 3,
    etc.
}

Ответ 2

Самый простой ответ: "Это не имеет значения".

Если параметр в вашем методе контроллера имеет тип перечисления

public IHttpActionResult Foo(RuleType ruleType)

В WebAPI, Just Just Works - независимо от того, указывает ли URL-адрес запроса клиента значение parmeter как ?ruleType=1 или ?ruleType=EmailAddress

Если клиент указывает значение, которое недопустимо для перечисления, генерируется исключение (The parameters dictionary contains a null entry for parameter 'ruleType' of non-nullable type 'RuleType' for method 'Foo'... и клиент получает ответ 400 Bad Request.

Ответ 3

Для сценария 2 встроенная поддержка в С# для операций битмаски в Enums с использованием атрибута [Flags]

[Flags]
public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    RuleAdministrator = 4,
    RuleEditor = 8,
    ...etc
}

Что описано в этом сообщении SO

Как уже сказал христианин в своем ответе, вероятно, не очень хорошая практика использовать это в REST API, но он должен работать.

Ответ 4

Несколько значений или нет, если вы используете Enum в качестве строки, вам нужно разобрать его вручную. В.NET перечисления являются целыми числами, поэтому, если вы хотите отправить перечисление в стандартное связующее устройство, вам нужно сделать это следующим образом ?ruleType=1.

Вы можете написать собственное связующее устройство, которое примет строку, но вы должны спросить себя, почему мы это делаем? Если вы хотите, чтобы пользователь мог легко идентифицировать URL-адрес, используйте строки. Если нет, нет причин не использовать целые числа. Как вы сказали, вы можете использовать FlagsAttribute для объединения нескольких значений.