Tipo complejo obtiene nulo en un parámetro ApiController

No sé por qué mi parámetro “ParametroFiltro Filtro” se está anulando, los otros parámetros “página” y “tamaño de página” están funcionando bien.

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

Mi método ApiController Get:

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

Mi llamada 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); } }); 

Está intentando enviar un objeto complejo con el método GET . El motivo por el que esto falla es que el método GET no puede tener un cuerpo y todos los valores se codifican en la URL. Puede hacer que esto funcione usando [FromUri] , pero primero debe cambiar el código del lado del 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); } }); 

De esta forma, [FromUri] podrá recoger sus propiedades de objeto complejas directamente desde la URL si cambia su método de acción de esta manera:

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

Su enfoque anterior preferiría trabajar con el método POST que puede tener un cuerpo (pero aún tendría que usar JSON.stringify() para formatear el cuerpo como JSON).

Proporcione la propiedad contentType cuando realice la llamada ajax. Use el método JSON.stringify para comstackr los datos JSON para publicar. cambie el tipo a POST y el enlace del modelo MVC vinculará los datos publicados a su objeto de clase.

 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); } }); 

Si anexa datos json a la cadena de consulta, y los analiza más adelante en el lado de la API web. también puedes analizar objetos complejos. Es útil en lugar de objeto json post, especialmente en algún caso de requisito especial de httpget.

 //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; } } 

También es posible acceder a las variables POST a través de un JObject de Newtonsoft.Json.Linq.

Por ejemplo, este POST:

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

Se puede acceder en un APIController así:

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