Почему мы должны указывать FromBody и FromUri?

Почему атрибуты FromBody и FromUri необходимы в ASP.NET Web API`?

В чем разница между использованием атрибутов и их использованием?

Ответ 1

Когда 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.

Ответ 2

Поведение по умолчанию:

  • Если параметр равен 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) { ... }

Причиной этого правила является то, что тело запроса может быть сохранено в небуферизованный поток, который можно прочитать только один раз.

Источник: https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api#using-frombody

Ответ 3

Когда параметр имеет [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