Необов’язкові параметри в маршрутизації атрибутів Web Api


89

Я хочу обробити POST наступного виклику API:

/v1/location/deviceid/appid

Додаткові параметри надходять від Post-Body.

Для мене все це чудово працює. Тепер я хочу розширити свій код, дозволивши значення "deviceid" та / або "appid" та / або BodyData нульовим:

/v1/location/deviceid
/v1/location/appid
/v1/location/

Ці 3 URL-адреси повинні відповідати тим же шляхом.

Мій перший підхід (потрібні BodyData):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData)
{
    return repository.AddNewLocation(deviceid, appid, BodyData);
}

Це не працює і повертає помилку компіляції:

"необов’язкові параметри повинні бути в кінці"

Наступна спроба:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null)

Тепер моя функція AddNewLocation () отримує завжди BodyData=null- навіть якщо виклик надсилає Body.

Нарешті я встановив усі 3 параметри необов’язково:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null)

Не працює:

Необов’язковий параметр BodyDataне підтримується FormatterParameterBinding.

Чому я хочу рішення з необов’язковими параметрами? Мій контролер обробляє лише "додавання нового розташування" через POST.

Я хочу надіслати на неправильних даних свої власні винятки або повідомлення про помилки. Навіть якщо у виклику відсутні значення. У цьому випадку я хочу мати можливість прийняти виключення або встановити за замовчуванням мій код.

Відповіді:


176

Для вхідного запиту типу /v1/location/1234, як ви можете собі уявити, веб-API буде важко автоматично з'ясувати, чи значення сегмента, що відповідає '1234', пов'язане, appidа не з deviceid.

Я думаю, вам слід змінити шаблон маршруту на подібний, [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]а потім проаналізувати його, deiveOrAppidщоб з’ясувати тип ідентифікатора.

Також вам потрібно зробити сегменти у самому шаблоні маршруту необов’язковими, інакше сегменти вважаються необхідними. Зверніть увагу на ?характер у цьому випадку. Наприклад: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]


56
?всередині шаблону маршруту - це те, що я шукав. +1
Kal_Torak

4
Я б не сказав, що "deviceOrAppId" - найкращий вибір дизайну. Я думаю, що API завжди повинен знати за визначенням, що він буде отримувати, якщо це можливо.
Нільс Брінч

14
Тільки для інформації - Коли ми позначаємо параметр як необов’язковий в uri дії за допомогою ?символу, тоді ми повинні вказати значення за замовчуванням для параметрів у підписі методу, наприклад MyMethod (ім’я рядка = "someDefaultValue", int? Id = null).
RBT

@RBT ти справжній MVP, я тупився там на хвилину. Дякую!
см

1
Класно. Радий, що це допомогло вам @sm. Я перетворив свій коментар на відповідь для кращої видимості, оскільки видається корисним. Це буде доповненням до поста Кірана.
RBT

45

Інша інформація: Якщо ви хочете використовувати обмеження маршруту , уявіть, що ви хочете примусити цей параметр мати тип даних int , тоді вам потрібно використовувати такий синтаксис:

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")]

? символ ставиться завжди перед останнім } символом

Для отримання додаткової інформації див .: Необов’язкові параметри URI та значення за замовчуванням


18

Перетворення мого коментаря у відповідь на доповнення відповіді @Kiran Chala, оскільки це видається корисним для аудиторії-

Коли ми позначаємо параметр як необов’язковий в uri дії за допомогою ?символу, тоді ми повинні вказати значення за замовчуванням для параметрів у підписі методу, як показано нижче:

MyMethod(string name = "someDefaultValue", int? Id = null)


Я збирався прокоментувати те саме.
Jnr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.