Tipo complexo está ficando nulo em um parâmetro ApiController

Eu não sei porque meu parâmetro “ParametroFiltro Filtro” está ficando nulo, os outros parâmetros “page” e “pageSize” estão ficando OK.

public class ParametroFiltro { public string Codigo { get; set; } public string Descricao { get; set; } } 

Meu método ApiController Get:

 public PagedDataModel Get(ParametroFiltro Filtro, int page, int pageSize) 

Minha chamada ajax:

 var fullUrl = "/api/" + self.Api; $.ajax({ url: fullUrl, type: 'GET', dataType: 'json', data: { Filtro: { Codigo: '_1', Descricao: 'TESTE' }, page: 1, pageSize: 10 }, success: function (result) { alert(result.Data.length); self.Parametros(result.Data); } }); 

Você está tentando enviar um object complexo com o método GET . A razão pela qual isso está falhando é que o método GET não pode ter um corpo e todos os valores estão sendo codificados na URL. Você pode fazer isso funcionar usando [FromUri] , mas primeiro você precisa alterar o código do lado do cliente:

 $.ajax({ url: fullUrl, type: 'GET', dataType: 'json', data: { Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 }, success: function (result) { alert(result.Data.length); self.Parametros(result.Data); } }); 

Dessa forma, o [FromUri] poderá selecionar suas propriedades complexas diretamente do URL, se você alterar seu método de ação da seguinte forma:

 public PagedDataModel Get([FromUri]ParametroFiltro Filtro, int page, int pageSize) 

Sua abordagem anterior preferiria trabalhar com o método POST , que pode ter um corpo (mas você ainda precisaria usar JSON.stringify() para formatar o corpo como JSON).

Forneça a propriedade contentType quando fizer a chamada do ajax. Use o método JSON.stringify para criar os dados JSON para postar. altere o tipo para POST e a vinculação do Modelo MVC vinculará os dados postados ao seu object de class.

 var filter = { "Filtro": { "Codigo": "_1", "Descricao": "TESTE" }, "page": "1", "pageSize": "10" }; $.ajax({ url: fullUrl, type: 'POST', dataType: 'json', contentType: 'application/json', data: JSON.stringify(filter), success: function (result) { alert(result.Data.length); self.Parametros(result.Data); } }); 

Se você acrescentar dados do json à string de consulta, e analisá-los mais tarde no lado da API da web. Você também pode analisar objects complexos. É útil em vez de postar o object json, especialmente em alguns casos especiais de requisitos de http.

 //javascript file var data = { UserID: "10", UserName: "Long", AppInstanceID: "100", ProcessGUID: "BF1CC2EB-D9BD-45FD-BF87-939DD8FF9071" }; var request = JSON.stringify(data); request = encodeURIComponent(request); doAjaxGet("/ProductWebApi/api/Workflow/StartProcess?data=", request, function (result) { window.console.log(result); }); //webapi file: [HttpGet] public ResponseResult StartProcess() { dynamic queryJson = ParseHttpGetJson(Request.RequestUri.Query); int appInstanceID = int.Parse(queryJson.AppInstanceID.Value); Guid processGUID = Guid.Parse(queryJson.ProcessGUID.Value); int userID = int.Parse(queryJson.UserID.Value); string userName = queryJson.UserName.Value; } //utility function: public static dynamic ParseHttpGetJson(string query) { if (!string.IsNullOrEmpty(query)) { try { var json = query.Substring(7, query.Length - 7); //seperate ?data= characters json = System.Web.HttpUtility.UrlDecode(json); dynamic queryJson = JsonConvert.DeserializeObject(json); return queryJson; } catch (System.Exception e) { throw new ApplicationException("can't deserialize object as wrong string content!", e); } } else { return null; } } 

Também é possível acessar variables ​​POST através de um JObject Newtonsoft.Json.Linq.

Por exemplo, este POST:

 $.ajax({ type: 'POST', url: 'URL', data: { 'Note': note, 'Story': story }, dataType: 'text', success: function (data) { } }); 

Pode ser acessado em um APIController da seguinte forma:

 public void Update([FromBody]JObject data) { var Note = (String)data["Note"]; var Story = (String)data["Story"]; }