create - serialize json c#
Devuelve JsonResult desde la api web sin sus propiedades (4)
Al usar WebAPI, solo debe devolver el Objeto en lugar de específicamente Json, ya que la API devolverá JSON o XML según la solicitud.
No estoy seguro de por qué su WebAPI está devolviendo un ActionResult, pero cambiaría el código a algo así como;
public IEnumerable<ListItems> GetAllNotificationSettings()
{
var result = new List<ListItems>();
// Filling the list with data here...
// Then I return the list
return result;
}
Esto resultará en JSON si lo llama desde algún código AJAX.
PS WebAPI se supone que es RESTful, por lo que su Controlador debería llamarse ListItemController
y su Método debería llamarse Get
. Pero eso es para otro día.
Tengo un controlador de API web y desde allí devuelvo un objeto como JSON desde una acción.
Lo estoy haciendo así:
public ActionResult GetAllNotificationSettings()
{
var result = new List<ListItems>();
// Filling the list with data here...
// Then I return the list
return new JsonResult { Data = result };
}
Pero de esta manera, el objeto JsonResult que incluye su atributo Data
se serializa como JSON. Así que mi JSON final que es devuelto por la acción se ve así:
{
"ContentEncoding": null,
"ContentType": null,
"Data": {
"ListItems": [
{
"ListId": 2,
"Name": "John Doe"
},
{
"ListId": 3,
"Name": "Jane Doe"
},
]
},
"JsonRequestBehavior": 1,
"MaxJsonLength": null,
"RecursionLimit": null
}
No puedo serializar esta cadena JSON porque el objeto JsonResult
agregó todo tipo de otras propiedades. Sólo estoy interesado en ListItems
, nada más. Pero automáticamente agregó cosas como: ContentType
, MaxJsonLength
, etc ...
Ahora esto no funcionará para mí debido a todas las otras propiedades en la cadena JSON ...
var myList = JsonConvert.DeserializeObject<List<ListItems>>(jsonString);
¿Hay alguna forma de enviar un objeto JSON desde la acción para que no agregue todas las propiedades que no necesito?
Como alguien que ha trabajado con la API de ASP.NET durante aproximadamente 3 años, recomendaría devolver un HttpResponseMessage en su lugar. ¡No uses ActionResult o IEnumerable!
ActionResult es malo porque como has descubierto.
Devolver IEnumerable <> es malo porque es posible que desee extenderlo más tarde y agregar algunos encabezados, etc.
El uso de JsonResult es malo porque debe permitir que su servicio se pueda extender y admitir otros formatos de respuesta, por si acaso en el futuro; Si realmente quieres limitarlo, puedes hacerlo usando Atributos de Acción, no en el cuerpo de la acción.
public HttpResponseMessage GetAllNotificationSettings()
{
var result = new List<ListItems>();
// Filling the list with data here...
// Then I return the list
return Request.CreateResponse(HttpStatusCode.OK, result);
}
En mis pruebas, generalmente uso el siguiente método auxiliar para extraer mis objetos del HttpResponseMessage:
public class ResponseResultExtractor
{
public T Extract<T>(HttpResponseMessage response)
{
return response.Content.ReadAsAsync<T>().Result;
}
}
var actual = ResponseResultExtractor.Extract<List<ListItems>>(response);
De esta manera, has logrado lo siguiente:
- Su Acción también puede devolver Mensajes de error y códigos de estado como 404 que no se encuentran, por lo que de la manera anterior puede manejarlo fácilmente.
- Su acción no se limita solo a JSON, sino que admite JSON según la preferencia de solicitud del cliente y la configuración del formateador.
Mira esto: http://www.asp.net/web-api/overview/formats-and-model-binding/content-negotiation
Tuve un problema similar (las diferencias eran que quería devolver un objeto que ya se había convertido en una cadena json y mi controlador obtiene devuelve un IHttpActionResult )
Así es como lo resolví. Primero declaré una clase de utilidad
public class RawJsonActionResult : IHttpActionResult
{
private readonly string _jsonString;
public RawJsonActionResult(string jsonString)
{
_jsonString = jsonString;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var content = new StringContent(_jsonString);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return Task.FromResult(response);
}
}
Esta clase puede ser utilizada en su controlador. Aquí hay un ejemplo simple.
public IHttpActionResult Get()
{
var jsonString = "{/"id/":1,/"name/":/"a small object/" }";
return new RawJsonActionResult(jsonString);
}
return JsonConvert.SerializeObject(images.ToList(), Formatting.None, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.None, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
using Newtonsoft.Json;