Чому потрібні атрибути FromBody
та FromUri
атрибути у веб-API ASP.NET?
Які відмінності між використанням атрибутів і не використанням їх?
Чому потрібні атрибути FromBody
та FromUri
атрибути у веб-API ASP.NET?
Які відмінності між використанням атрибутів і не використанням їх?
Відповіді:
Коли веб-API ASP.NET викликає метод на контролері, він повинен встановлювати значення параметрів - процес, який називається прив'язка параметрів .
За замовчуванням Web API використовує такі правила для прив’язки параметрів:
Якщо параметр типу "простий" , Web API намагається отримати значення з URI . До простих типів належать примітивні типи .NET (int, bool, double та ін.), Плюс TimeSpan, DateTime, Guid, десяткові та рядкові, а також будь-який тип із конвертором типів, який може конвертувати з рядка.
Для складних типів Web API намагається прочитати значення з тіла повідомлення , використовуючи формат медіа-типу.
Отже, якщо ви хочете змінити вищезазначене поведінку за замовчуванням і змусити Web API прочитати складний тип з URI, додайте [FromUri]
атрибут до параметра. Щоб змусити веб-API прочитати простий тип з тіла запиту, додайте [FromBody]
атрибут до параметра.
Отже, щоб відповісти на ваше запитання, потреба атрибутів [FromBody]
і [FromUri]
атрибутів у веб-API - це просто перекрити, якщо необхідно, поведінку за замовчуванням, як описано вище. Зауважте, що ви можете використовувати обидва атрибути для методу контролера, але тільки для різних параметрів, як показано тут .
В Інтернеті є набагато більше інформації, якщо ви перейдете на Google "прив'язка параметрів web 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 щодо прив'язки параметрів у веб-API ASP.NET :
Коли параметр має [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