unity remarks net method generate example description comentarios c# jquery ajax json asp.net-web-api

c# - remarks - Las propiedades de los parámetros complejos de la API web son todas nulas



remarks c# (11)

Debido a que este problema me preocupó durante casi un día completo de trabajo ayer, quiero agregar algo que pueda ayudar a otros en la misma situación.

Utilicé Xamarin Studio para crear mi proyecto de api angular y web. Durante la depuración, el objeto pasaría por nulo algunas veces y como objeto poblado otras veces. Solo cuando empecé a depurar mi proyecto en Visual Studio, mi objeto se rellenó en cada solicitud de publicación. Esto parece ser un problema al depurar en Xamarin Studio.

Intente la depuración en Visual Studio si está ejecutando este problema de parámetro nulo con otro IDE.

Tengo una llamada de servicio de API web que actualiza las preferencias de un usuario. Desafortunadamente, cuando llamo a este método POST desde una llamada jQuery ajax, las propiedades del objeto de parámetro de solicitud siempre son nulas (o valores predeterminados), en lugar de lo que se pasa. Si llamo al mismo método exacto usando un cliente REST (uso Postman) , funciona muy bien. No puedo entender qué estoy haciendo mal con esto, pero espero que alguien haya visto esto antes. Es bastante sencillo ...

Aquí está mi objeto de solicitud:

public class PreferenceRequest { [Required] public int UserId; public bool usePopups; public bool useTheme; public int recentCount; public string[] detailsSections; }

Aquí está mi método de controlador en la clase UserController:

public HttpResponseMessage Post([FromBody]PreferenceRequest request) { if (request.systemsUserId > 0) { TheRepository.UpdateUserPreferences(request.UserId, request.usePopups, request.useTheme, request.recentCount, request.detailsSections); return Request.CreateResponse(HttpStatusCode.OK, "Preferences Updated"); } else { return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "You must provide User ID"); } }

Aquí está mi llamada ajax:

var request = { UserId: userId, usePopups: usePopups, useTheme: useTheme, recentCount: recentCount, detailsSections: details }; $.ajax({ type: "POST", data: request, url: "http://localhost:1111/service/User", success: function (data) { return callback(data); }, error: function (error, statusText) { return callback(error); } });

He intentado establecer dataType y contentType en varias cosas diferentes (''json'', ''application / json'', etc.) pero las propiedades del objeto de solicitud siempre tienen un valor predeterminado o son nulas. Así, por ejemplo, si paso en este objeto:

var request = { UserId: 58576, usePopups: false, useTheme: true, recentCount: 10, detailsSections: [''addresses'', ''aliases'', ''arrests'', ''events'', ''classifications'', ''custody'', ''identifiers'', ''phone'', ''remarks'', ''watches''] }

Puedo ver un objeto de solicitud completamente rellenado con los valores válidos como se indica arriba. Pero en el controlador de la API web, la solicitud está allí, pero las propiedades son las siguientes:

UserId: 0, usePopups: false, useTheme: false, recentCount: 0, detailsSections: null

Para su información, no estoy haciendo NINGUNA página ASP.Net MVC o ASP.NET con este proyecto, solo uso la API web como un servicio y todas las llamadas utilizando jQuery $ .ajax.

¿Alguna idea de lo que estoy haciendo mal aquí? ¡Gracias!

ACTUALIZACIÓN: solo quiero señalar que tengo muchos métodos en este mismo proyecto de API web en otros controladores que hacen exactamente lo mismo , y estoy llamando exactamente de la misma manera , ¡y funcionan perfectamente! He pasado la mañana comparando las distintas llamadas, y no parece haber ninguna diferencia en el método o los encabezados, y sin embargo, simplemente no funciona en este método en particular.

También he intentado cambiar a un método Put, pero obtengo exactamente los mismos resultados: el objeto de solicitud aparece, pero no se rellena con los valores correctos. Lo que es tan frustrante es que tengo alrededor de 20 clases de controladores en este proyecto, y las publicaciones funcionan en todas esas ...


El uso de esta técnica publicada por @blorkfish funcionó muy bien:

$.ajax({ type: "POST", data: JSON.stringify(request);, dataType: ''json'', contentType: "application/json", url: "http://localhost:1111/service/User",

Tenía un objeto de parámetro, que tenía un par de tipos nativos y un par de objetos más como propiedades. Los objetos tenían constructores marcados como internos y la llamada JsonConvert.DeserializedObject en el jsonString dio el error:

No se puede encontrar un constructor para usar para el tipo ChildObjectB. Una clase debe tener un constructor predeterminado, un constructor con argumentos o un constructor marcado con el atributo JsonConstructor.

Cambié los constructores a públicos y ahora está rellenando el objeto de parámetro cuando reemplazo el parámetro del modelo de Objeto con el objeto real. ¡Gracias!


Esto parece ser un problema común con respecto a Asp.Net WebAPI.
En general, la causa de los objetos nulos es la deserialización del objeto json en el objeto C #. Desafortunadamente, es muy difícil de depurar y, por tanto, encontrar dónde está su problema.
Prefiero enviar el json completo como un objeto y luego deserializar manualmente. Al menos de esta forma obtendrás errores reales en lugar de nulos.
Si cambia su firma de método para aceptar un objeto, entonces use JsonConvert:

public HttpResponseMessage Post(Object model) { var jsonString = model.ToString(); PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString); }


Hoy tengo el mismo problema que el tuyo. Cuando envío POST solicitud POST desde ajax el controlador recibe un objeto vacío con valores de propiedad Null y predeterminados. El método es:

[HttpPost] public async Task<IActionResult> SaveDrawing([FromBody]DrawingModel drawing) { try { await Task.Factory.StartNew(() => { //Logic }); return Ok(); } catch(Exception e) { return BadRequest(); } }

Mi tipo de Content-Type era correcto y todo lo demás era correcto también. Después de probar muchas cosas, encontré que enviar el objeto de esta manera:

$.ajax({ url: ''/DrawingBoard/SaveDrawing'', type: ''POST'', contentType: ''application/json'', data: dataToPost }).done((response) => { });

No funcionará, pero enviarlo así funcionó:

$.ajax({ url: ''/DrawingBoard/SaveDrawing'', type: ''POST'', contentType: ''application/json'', data: JSON.stringify(dataToPost) }).done((response) => { });

Sí, la falta de JSON.stringify() causó todo el problema, y ​​no hay necesidad de poner = o cualquier otra cosa como prefijo o sufijo en JSON.stringify . Después de cavar un poco. Encontré que el formato de la carga útil de solicitud es completamente diferente entre las dos solicitudes
Esta es la carga útil de solicitud con JSON.stringify

Y esta es la carga útil de solicitud sin JSON.stringify

Y no se olvide, cuando las cosas se ponen mágicas y utiliza Google Chrome para probar su aplicación web. Hacer caché vacío y recargar duro de vez en cuando.


Lo sé, es un poco tarde, pero me encontré con el mismo problema. La respuesta de @blorkfish también funcionó para mí, pero me llevó a una solución diferente. Una de las partes de mi objeto complejo carecía de un constructor sin parámetros. Después de agregar este constructor, tanto las solicitudes Put como Post comenzaron a funcionar como se esperaba.


Me encontré con el mismo problema, la solución para mí era asegurarse de que los tipos de mis atributos de clase coincidían con los atributos de json, quiero decir

Json: "attribute": "true"

Debería tratarse como una cadena y no como un valor booleano, parece que si tiene un problema como este, todos los atributos debajo del atributo defectuoso quedarán predeterminados en nulo


Me encontré con el mismo problema. La solución necesaria fue asegurar que todas las propiedades capaces de ser serializadas para su JSON a la clase de parámetros se hayan obtenido; conjunto; Métodos explícitamente definidos. ¡No confíe en la sintaxis de propiedad automática de C #! Espero que esto se solucione en versiones posteriores de asp.net.


Supongo que el problema es que su controlador espera el tipo de contenido de [FromBody], intente cambiar su controlador a

public HttpResponseMessage Post(Object model) { var jsonString = model.ToString(); PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString); }

y ajax a

public HttpResponseMessage Post(PreferenceRequest request)

Por cierto, crear un modelo en javascript puede no ser la mejor práctica.


Tal vez ayude, yo estaba teniendo el mismo problema.

Todo funcionaba bien y, de repente, todas las propiedades estaban predeterminadas.

Después de una prueba rápida, descubrí que era el [Serializable] el que estaba causando el problema :

public IHttpActionResult Post(MyComplexClass myTaskObject) { //MyTaskObject is not null, but every member are (the constructor get called). }

Y aquí estaba un fragmento de mi clase:

[Serializable] <-- have to remove that [if it was added for any reason..] public class MyComplexClass() { public MyComplexClass () { ..initiate my variables.. } public string blabla {get;set;} public int intTest {get;set; }


También me he enfrentado a este problema y, después de muchas horas de debbug y de investigación, he notado que el problema no fue causado por los atributos Content-Type o Type $ Ajax, el problema fue causado por valores NULL en mi objeto JSON, es un problema muy grosero ya que POST no crea, pero una vez que se corrigen los valores NULL, la POST estaba bien y se emitió de forma nativa a mi clase de respuestaComparacion aquí el código:

JSON

respuestaComparacion: { anioRegistro: NULL, --> cannot cast to BOOL claveElector: NULL, --> cannot cast to BOOL apellidoPaterno: true, numeroEmisionCredencial: false, nombre: true, curp: NULL, --> cannot cast to BOOL apellidoMaterno: true, ocr: true }

Controlador

[Route("Similitud")] [HttpPost] [AllowAnonymous] public IHttpActionResult SimilitudResult([FromBody] RespuestaComparacion req) { var nombre = req.nombre; }

Clase

public class RespuestaComparacion { public bool anioRegistro { get; set; } public bool claveElector { get; set; } public bool apellidoPaterno { get; set; } public bool numeroEmisionCredencial { get; set; } public bool nombre { get; set; } public bool curp { get; set; } public bool apellidoMaterno { get; set; } public bool ocr { get; set; } }

Espero que esto ayude.


Un poco tarde para la fiesta, pero tuve el mismo problema y la solución fue declarar el tipo de contenido en su llamada ajax:

var settings = { HelpText: $(''#help-text'').val(), BranchId: $("#branch-select").val(), Department: $(''input[name=departmentRadios]:checked'').val() }; $.ajax({ url: ''http://localhost:25131/api/test/updatesettings'', type: ''POST'', data: JSON.stringify(settings), contentType: "application/json;charset=utf-8", success: function (data) { alert(''Success''); }, error: function (x, y, z) { alert(x + ''/n'' + y + ''/n'' + z); } });

Y su controlador de API se puede configurar de esta manera:

[System.Web.Http.HttpPost] public IHttpActionResult UpdateSettings([FromBody()] UserSettings settings) { //do stuff with your UserSettings object now return Ok("Successfully updated settings"); }