it-swarm.com.ru

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

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

Сценарий 1: Прямой Enum Param

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

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

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

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

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

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

Это Enum:

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

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

13
marcusstarnes

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

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

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

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

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

public IHttpActionResult Foo(RuleType ruleType)

В WebAPI, Это просто работает - независимо от того, указывает ли URL-адрес запроса клиента значение параметра в виде ?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).

8
Mr. T

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

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

Который описан в этом SO посте

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

2
Chris W

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

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

0
Hristo Kolev