Por que os atributos FromBody
e FromUri
são necessários na API da Web do ASP.NET?
Quais são as diferenças entre usar os atributos e não usá-los?
Por que os atributos FromBody
e FromUri
são necessários na API da Web do ASP.NET?
Quais são as diferenças entre usar os atributos e não usá-los?
Respostas:
Quando a API da Web do ASP.NET chama um método em um controlador, deve definir valores para os parâmetros, um processo chamado ligação de parâmetro .
Por padrão, a API da Web usa as seguintes regras para ligar parâmetros:
Se o parâmetro for do tipo "simples" , a API da Web tentará obter o valor do URI . Tipos simples incluem os tipos primitivos do .NET (int, bool, double e assim por diante), além de TimeSpan, DateTime, Guid, decimal e string, além de qualquer tipo com um conversor de tipo que possa converter de uma string.
Para tipos complexos , a API da Web tenta ler o valor do corpo da mensagem , usando um formatador de tipo de mídia.
Portanto, se você deseja substituir o comportamento padrão acima e forçar a API da Web a ler um tipo complexo a partir do URI, adicione o [FromUri]
atributo ao parâmetro Para forçar a API da Web a ler um tipo simples do corpo da solicitação, adicione o [FromBody]
atributo ao parâmetro
Portanto, para responder sua pergunta, a necessidade dos atributos [FromBody]
e [FromUri]
na API da Web é simplesmente substituir, se necessário, o comportamento padrão conforme descrito acima. Observe que você pode usar os dois atributos para um método do controlador, mas apenas para parâmetros diferentes, conforme demonstrado aqui .
Há muito mais informações na web se você pesquisar no Google "vinculação de parâmetros da API da Web".
JustGetIt
que serve a mesma finalidade de adicionar vários atributos como [FromBody, FromQuery]
etc
O comportamento padrão é:
Se o parâmetro é um primitivo tipo ( int
, bool
, double
, ...), tentativas Web API para obter o valor do URI da solicitação HTTP.
Para tipos complexos (seu próprio objeto, por exemplo Person
:), a API da Web tenta ler o valor do corpo da solicitação HTTP.
Então, se você tem:
... então você não precisa adicionar nenhum atributo (nem [FromBody]
nem [FromUri]
).
Mas, se você tiver um tipo primitivo no corpo , precisará adicionar [FromBody]
na frente do seu parâmetro de tipo primitivo no método do controlador WebAPI. (Como, por padrão, o WebAPI está procurando tipos primitivos no URI da solicitação HTTP).
Ou, se você tiver um tipo complexo em seu URI , deverá adicionar [FromUri]
. (Como, por padrão, o WebAPI está procurando tipos complexos no corpo da solicitação HTTP, por padrão).
Tipos primitivos:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Tipos complexos:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
Isso funciona desde que você envie apenas um parâmetro na sua solicitação HTTP. Ao enviar vários , você precisa criar um modelo personalizado com todos os seus parâmetros como este:
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;
}
Na documentação da Microsoft para ligação de parâmetros na API da Web do ASP.NET :
Quando um parâmetro possui [FromBody], a API da Web usa o cabeçalho Content-Type para selecionar um formatador. Neste exemplo, o tipo de conteúdo é "application / json" e o corpo da solicitação é uma sequência JSON bruta (não um objeto JSON). No máximo, um parâmetro pode ler do corpo da mensagem.
Isso deve funcionar:
public HttpResponseMessage Post([FromBody] string name) { ... }
Isso não vai funcionar:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
O motivo dessa regra é que o corpo da solicitação pode ser armazenado em um fluxo sem buffer que pode ser lido apenas uma vez.
Apenas adição às respostas acima ..
[FromUri] também pode ser usado para vincular tipos complexos a partir de parâmetros uri em vez de passar parâmetros da querystring
Para Ex ..
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) { ... }
}
Pode ser chamado como:
http://localhost/api/values/47.678558/-122.130989
Quando um parâmetro possui [FromBody], a API da Web usa o cabeçalho Content-Type para selecionar um formatador. Neste exemplo, o tipo de conteúdo é "application / json" e o corpo da solicitação é uma sequência JSON bruta (não um objeto JSON).
No máximo, um parâmetro pode ler do corpo da mensagem. Portanto, isso não vai funcionar:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
O motivo dessa regra é que o corpo da solicitação pode ser armazenado em um fluxo sem buffer que pode ser lido apenas uma vez
Visite o site para obter mais detalhes: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api