ASP .NET Web API - Passando múltiplos parâmetros usando jQuery
Neste artigo veremos passar múltiplos parãmetros para uma API ASP .NET MVC 5 usando jQuery. |
As Web APIs criadas via ASP .NET MVC 5 possuem algumas restrições para mapear variáveis de formulário POST para parâmetros simples de um método Action da API. A Web API não lida com vários valores de conteúdo postados.
Você só pode postar um único valor de conteúdo em um método Action da API e neste artigo veremos as diferentes maneiras de passar vários parâmetros para o método Action de uma Web API.
Suponha que você tenha o seguinte método na sua Web API definida em um controller ProdutosController:
public HttpResponseMessage PostProduto(int Id, string Nome, int Estoque, decimal Preco)
{
//seu código
} |
E você esta tentando fazer a seguinte chamada usando jQuery:
$.ajax({
url: 'api/produtos',
type: 'POST',
data: { Id: 2012, Nome: 'teste', Estoque:
55, Preco: 19.5 },
dataType: 'json',
success: function (data) {
alert(data);
}
});
|
Infelizmente, a WEB API não vai poder tratar esta requisição, e, você vai obter um erro.
Para obter sucesso você tem que passar os parâmetros usando uma query string, assim :
$.ajax({
url: 'api/produtos?Id=2012&Nome=teste&Estoque=55&Preco=19.5',
type: 'POST',
dataType: 'json',
success: function (data) {
alert(data);
}
});
|
Funcionar, funciona, mas não é uma boa solução e não é aplicável a objetos complexos.
Então, vejamos a seguir outras maneiras de fazer isso...
Usando o Model Binding
O model binding permite mapear dados de uma requisição HTTP para um modelo,em um processo de criar objetos .NET usando os dados enviados pelo navegador em uma requisição HTTP.
O model binding funciona como uma ponte projetada entre os métodos HTTP e os métodos Action da API. Neste contexto o POST, GET, DELETE, PUT, etc. são transferidos automaticamente para um modelo de dados definido.
Como exemplo vamos criar um modelo representado pela classe Produto:
public class Produto
{
public int Id { get; set; }
public string Nome { get; set; }
public string Categoria { get; set; }
public decimal Preco { get; set; }
}
|
Agora vamos usar esse modelo de domínio em um controlador ProdutosController como um argumento no método Action PostProduto:
public
HttpResponseMessage PostProduto(Produto
item)
{
item = repository.Add(item);
var response = Request.CreateResponse<Produto>(HttpStatusCode.Created,
item);
string uri = Url.Link("DefaultApi", new { id = item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
|
Para fazer uma chamada para este método via jQuery podemos fazer assim:
$.ajax({
url: 'api/produtos',
type: 'POST',
data:
{ Id: 2012, Nome: 'teste', Estoque: 44, Preco: 19.5 },
dataType: 'json',
success: function (data) {
alert(data);
}
});
|
Agora vai funcionar, graças ao model binding.
Podemos obter o mesmo resultado de outra forma fazendo assim:
var
produto = { Id: 2012, Nome:
'teste', Estoque: 44, Preco: 19.5 }
$.ajax({
url: 'api/produtos',
type: 'POST',
data:
JSON.stringify(produto),
dataType: 'json',
success: function (data) {
alert(data);
}
});
|
Nota: JSON.stringify() é uma função do objeto JSON que criará uma string do objeto dentro do padrão adotado pelo JSON.
Assim também vai funcionar graças ao model binding.
Usando o binding de parâmetros customizado
A Web API da ASP.NET permite criar uma vinculação de parâmetro personalizada para estender a funcionalidade e permite que você intercepte o processamento de parâmetros individuais.
a- Usando JObject
Agora, a ASP .NET WEB usa o JSON.NET como serializador JSON. Assim, você pode usar a classe JObject para receber um resultado JSON dinâmico, convertê-lo corretamente ou analisá-lo na forma de objetos fortemente tipados.
Veja o exemplo abaixo:
public HttpResponseMessage PostProduto(JObject
data)
{
dynamic json = data;
Produto item = new Produto() {
Id =
json.Id,
Nome =
json.Nome,
Estoque =
json.Estoque,
Preco
=json.Preco
};
item = repository.Add(item);
var response =
Request.CreateResponse<Produto>(HttpStatusCode.Created, item);
string uri = Url.Link("DefaultApi", new { id =
item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
|
Ou de uma forma mais direta podemos tratar os dados em uma classe fortemente tipada:
public HttpResponseMessage PostProduto(JObject
data)
{
Produto item =
data.ToObject<Produto>();
item = repository.Add(item);
var response = Request.CreateResponse<Produto>(HttpStatusCode.Created,
item);
string uri = Url.Link("DefaultApi", new { id =
item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
|
b- Usando FormDataCollection
Outra opção é você definir o argumento do tipo FormDataCollection e ler cada parâmetro um por um manualmente usando os métodos .Get() ou .GetValues() (para valores de seleção múltipla).
Veja o exemplo a seguir para os dados: data : { Id: 2019 , Nome= 'teste, Estoque : 44, Preco: 19.5 }
Podemos fazer assim:
public HttpResponseMessage PostProduto(FormDataCollection
data)
{
Produto item = new Produto() {
Id =
Convert.ToInt32(data.Get("Id")),
Nome =
data.Get("Nome"),
Estoque =
Convert.ToInt32(data.Get("Estoque")),
Preco =
Convert.ToDecimal(data.Get("Preco"))
};
item = repository.Add(item);
var response =
Request.CreateResponse<Produto>(HttpStatusCode.Created, item);
string uri = Url.Link("DefaultApi", new { id =
item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
|
E se você quiser retornar múltiplos parâmetros ?
A primeira coisa a fazer é usar um Model com todos os parâmetros e retornar sua instância.
Mas não podemos criar um modelo para cada tipo de retorno a cada requisição.
Se todos os parâmetros tiverem o mesmo tipo de dados, podemos criar e retornar uma coleção. Mas os parâmetros podem ter tipos de dados diferentes.
E ai ?
Neste caso a solução mais simples é usar o tipo de retorno dynamic.
public dynamic GetProdutos()
{
var produtos = repository.GetAll() as
IEnumerable<Produto>;
return new
{
Produtos = produtos,
Criteria = "definido"
};
}
|
Vimos assim algumas maneiras de passar mais de um parâmetro em requisições para uma API.
"E
não temais os que matam o corpo e não podem matar a alma; temei antes aquele que
pode fazer perecer no inferno a alma e o corpo."
Mateus 10:28
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Apresentando LINQ - Language Integrated Query - Macoratti.net
ASP .NET MVC - Criando uma aplicação básica ... - Macoratti.net
ASP .NET MVC - Usando o MvcScaffolding package ... - Macoratti.net
ASP .NET MVC 5 - Cenário Mestre-Detalhes ... - Macoratti.net
EF Core 2.0 - Scaffolding DbContext e Models usando ... - Macoratti.net
ASP .NET MVC - Filtrando registros com Dropdownlist - Macoratti.net
ASP .NET - Carregando dados XML em um DropdownList - Macoratti.net
ASP .NET - Carregando uma lista de países sem usar ... - Macoratti.net
ASP .NET MVC - Filtrando registros com Dropdownlist - Macoratti.net
ASP .NET MVC - Movendo itens entre dois DropDownList com jQuery