Почему FromBody
и FromUri
атрибуты , необходимые в ASP.NET Web API`?
Каковы различия между использованием атрибутов и неиспользованием их?
Почему FromBody
и FromUri
атрибуты , необходимые в ASP.NET Web API`?
Каковы различия между использованием атрибутов и неиспользованием их?
Ответы:
Когда ASP.NET Web API вызывает метод на контроллере, он должен установить значения для параметров, процесс, называемый привязкой параметров .
По умолчанию веб-API использует следующие правила для привязки параметров:
Если параметр имеет «простой» тип , Web API пытается получить значение из URI . К простым типам относятся типы примитивов .NET (int, bool, double и т. Д.), А также TimeSpan, DateTime, Guid, decimal и string, а также любой тип с преобразователем типов, который может преобразовывать строки.
Для сложных типов Web API пытается прочитать значение из тела сообщения , используя средство форматирования медиа-типа.
Поэтому, если вы хотите переопределить вышеуказанное поведение по умолчанию и заставить Web API считывать сложный тип из URI, добавьте [FromUri]
атрибут к параметру. Чтобы заставить Web API читать простой тип из тела запроса, добавьте[FromBody]
атрибут к параметру.
Таким образом, чтобы ответить на ваш вопрос, то потребность [FromBody]
и [FromUri]
атрибуты в Web API является просто переопределить, если это необходимо, поведение по умолчанию , как описано выше. Обратите внимание, что вы можете использовать оба атрибута для метода контроллера, но только для разных параметров, как показано здесь .
В Интернете можно найти гораздо больше информации, если вы воспользуетесь «привязкой параметров веб-API».
JustGetIt
который служит той же самой цели, добавив несколько атрибутов, например, и [FromBody, FromQuery]
т. Д.
Поведение по умолчанию:
Если параметр является примитивным типом ( int
, bool
, double
...), Web API пытается получить значение из URI запроса HTTP.
Для сложных типов (ваш собственный объект, например Person
:) Web API пытается прочитать значение из тела HTTP-запроса.
Итак, если у вас есть:
... тогда вам не нужно добавлять какие-либо атрибуты ( [FromBody]
ни[FromUri]
).
Но если у вас есть примитивный тип в теле , то вы должны добавить[FromBody]
перед параметром примитивного типа в методе контроллера WebAPI. (Поскольку по умолчанию WebAPI ищет типы примитивов в URI HTTP-запроса.)
Или, если у вас есть сложный тип в вашем URI , то вы должны добавить [FromUri]
. (Поскольку по умолчанию WebAPI ищет сложные типы в теле HTTP-запроса по умолчанию.)
Примитивные типы:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Сложные типы:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
Это работает до тех пор, пока вы отправляете только один параметр в своем HTTP-запросе. При отправке нескольких вам нужно создать собственную модель, которая имеет все ваши параметры, например:
public class MyModel
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
// model.MyProperty;
// model.MyProperty2;
}
Из документации Microsoft по привязке параметров в ASP.NET Web API :
Если параметр имеет значение [FromBody], веб-API использует заголовок Content-Type для выбора средства форматирования. В этом примере тип содержимого - «application / json», а тело запроса - необработанная строка JSON (не объект JSON). Не более одного параметра разрешено читать из тела сообщения.
Это должно работать:
public HttpResponseMessage Post([FromBody] string name) { ... }
Это не будет работать:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Причина этого правила заключается в том, что тело запроса может храниться в небуферизованном потоке, который может быть прочитан только один раз.
Просто дополнение к ответам выше.
[FromUri] также может использоваться для связывания сложных типов из параметров URI вместо передачи параметров из строки запроса
Например
public class GeoPoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
[Route("{Latitude}/{Longitude}")]
public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}
Можно назвать как:
http://localhost/api/values/47.678558/-122.130989
Если параметр имеет значение [FromBody], веб-API использует заголовок Content-Type для выбора средства форматирования. В этом примере тип содержимого - «application / json», а тело запроса - необработанная строка JSON (не объект JSON).
Не более одного параметра разрешено читать из тела сообщения. Так что это не сработает
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Причина этого правила заключается в том, что тело запроса может храниться в небуферизованном потоке, который может быть прочитан только один раз.
Пожалуйста, посетите веб-сайт для получения более подробной информации: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api