Почему атрибуты FromBody
и FromUri
необходимы в ASP.NET Web API`?
В чем разница между использованием атрибутов и их использованием?
Почему атрибуты FromBody
и FromUri
необходимы в ASP.NET Web API`?
В чем разница между использованием атрибутов и их использованием?
Когда ASP.NET Web API вызывает метод на контроллере, он должен устанавливать значения для параметров, процесс, называемый привязкой параметров.
По умолчанию Web API использует следующие правила для привязки параметров:
Если параметр является "простым", Web API пытается получить значение из URI. Простые типы включают в себя примитивные типы .NET(int, bool, double и т.д.), А также TimeSpan, DateTime, Guid, decimal и string, а также любой тип с конвертером типов, который может конвертировать из строки.
Для сложных типов Web API пытается прочитать значение из тела сообщения с использованием форматера медиа-типа.
Итак, если вы хотите переопределить вышеуказанное поведение по умолчанию и заставить Web API читать сложный тип из URI, добавьте к параметру атрибут [FromUri]
. Чтобы заставить Web API читать простой тип из тела запроса, добавьте атрибут [FromBody]
к параметру.
Итак, чтобы ответить на ваш вопрос, необходимость атрибутов [FromBody]
и [FromUri]
в веб-API просто переопределить, если необходимо, поведение по умолчанию, как описано выше. Обратите внимание, что вы можете использовать оба атрибута для метода контроллера, но только для разных параметров, как показано здесь.
Существует много больше информация в Интернете, если вы переводите параметр "привязка к веб-атрибуту" Google.
Поведение по умолчанию:
Если параметр равен primitive type (int, bool, double, ...)
, Web API пытается получить значение из URI
HTTP-запроса.
Для complex types (your own object, for example: Person)
Web API пытается прочитать значение из body
HTTP-запроса.
Если у вас есть primitive type
в URI
или у вас есть complex type
в body
, вам не нужно добавлять какие-либо атрибуты (не [FromBody]
и [FromUri]
).
Но если в теле есть primitive type
, вам нужно добавить [FromBody]
перед вашим параметром primitive type
в свой метод контроллера WebAPI (потому что по умолчанию WebAPI ищет primitive types
в URI
HTTP-запроса), или если у вас есть complex type
в URI
, тогда вы должны добавить [FromUri]
(потому что по умолчанию WebAPI
ищет complex types
в body
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;
}
Когда параметр имеет [FromBody], Web API использует заголовок Content-Type для выбора форматирования. В этом примере тип содержимого "application/json", а тело запроса - это строка JSON с сыром (не JSON). Не более одного параметра разрешено читать из сообщение тело.
Это должно работать:
public HttpResponseMessage Post([FromBody] string name) { ... }
Это не сработает:
// Caution: Will not work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Причиной этого правила является то, что тело запроса может быть сохранено в небуферизованный поток, который можно прочитать только один раз.
Когда параметр имеет [FromBody], Web 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