Подтвердить что ты не робот

Необязательные параметры в маршрутизации атрибутов Web Api

Я хочу обрабатывать POST из следующего API-вызова:

/v1/location/deviceid/appid

Дополнительные параметры поступают из пост-тела.

Все это отлично работает для меня. Теперь я хочу расширить свой код, разрешив "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 - даже если вызов отправляет тело.

Наконец, я устанавливаю все 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.

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Другая информация. Если вы хотите использовать Ограничение маршрута, представьте, что вы хотите заставить этот параметр иметь тип int, тогда вам нужно использовать этот синтаксис:

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

Символ ? всегда ставится перед последним символом }

Для получения дополнительной информации см. Дополнительные параметры URI и значения по умолчанию

Ответ 3

Преобразование моего комментария в ответ, чтобы дополнить @Kiran Chala ответ, поскольку он кажется полезным для аудитории -

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

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