asp.net-mvc json serialization camelcasing

asp.net mvc - MVC JsonResult camelCase serialización



asp.net-mvc serialization (2)

Las funciones Json del controlador son solo envoltorios para crear JsonResults:

protected internal JsonResult Json(object data) { return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet); } protected internal JsonResult Json(object data, string contentType) { return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet); } protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) { return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet); } protected internal JsonResult Json(object data, JsonRequestBehavior behavior) { return Json(data, null /* contentType */, null /* contentEncoding */, behavior); } protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) { return Json(data, contentType, null /* contentEncoding */, behavior); } protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { return new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior }; }

JsonResult usa internamente JavaScriptSerializer, por lo que no tiene control sobre el proceso de serialización:

public class JsonResult : ActionResult { public JsonResult() { JsonRequestBehavior = JsonRequestBehavior.DenyGet; } public Encoding ContentEncoding { get; set; } public string ContentType { get; set; } public object Data { get; set; } public JsonRequestBehavior JsonRequestBehavior { get; set; } /// <summary> /// When set MaxJsonLength passed to the JavaScriptSerializer. /// </summary> public int? MaxJsonLength { get; set; } /// <summary> /// When set RecursionLimit passed to the JavaScriptSerializer. /// </summary> public int? RecursionLimit { get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed); } HttpResponseBase response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) { response.ContentType = ContentType; } else { response.ContentType = "application/json"; } if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } if (Data != null) { JavaScriptSerializer serializer = new JavaScriptSerializer(); if (MaxJsonLength.HasValue) { serializer.MaxJsonLength = MaxJsonLength.Value; } if (RecursionLimit.HasValue) { serializer.RecursionLimit = RecursionLimit.Value; } response.Write(serializer.Serialize(Data)); } } }

Tienes que crear tu propio JsonResult y escribir tus propias funciones de Json Controller (si necesitas / quieres eso). Puede crear nuevas o sobrescribir las existentes, depende de usted. Este link también podría interesarte.

Esta pregunta ya tiene una respuesta aquí:

Estoy tratando de hacer que mi acción devuelva un JsonResult donde todas sus propiedades están en camelCase.

Tengo un modelo simple:

public class MyModel { public int SomeInteger { get; set; } public string SomeString { get; set; } }

Y una acción de controlador simple:

public JsonResult Index() { MyModel model = new MyModel(); model.SomeInteger = 1; model.SomeString = "SomeString"; return Json(model, JsonRequestBehavior.AllowGet); }

Llamar a este método de acción ahora devuelve un JsonResult que contiene los siguientes datos:

{"SomeInteger":1,"SomeString":"SomeString"}

Para mis usos, necesito la acción devolver los datos en camelCase, de alguna manera así:

{"someInteger":1,"someString":"SomeString"}

¿Hay alguna forma elegante de hacer esto?

Estaba buscando posibles soluciones por aquí y encontré MVC3 JSON serialización: ¿Cómo controlar los nombres de las propiedades? donde establecen definiciones de DataMember para cada propiedad del modelo, pero realmente no quiero hacer esto.

También encontré un enlace donde dicen que es posible resolver exactamente este tipo de problema: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#json_camelcasing . Dice:

Para escribir nombres de propiedades JSON con carcasa de camello, sin cambiar su modelo de datos, configure CamelCasePropertyNamesContractResolver en el serializador:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

Una entrada en este blog http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/ también menciona esta solución y afirma que simplemente puede agregarla al RouteConfig.RegisterRoutes para solucionar este problema. Lo intenté, pero no pude hacerlo funcionar.

¿Tienen alguna idea de dónde estaba haciendo algo mal?


Si desea devolver una cadena json de su acción que se adhiere a la notación camelcase, lo que debe hacer es crear una instancia JsonSerializerSettings y pasarla como el segundo parámetro del método JsonConvert.SerializeObject (a, b).

public string GetSerializedCourseVms() { var courses = new[] { new CourseVm{Number = "CREA101", Name = "Care of Magical Creatures", Instructor ="Rubeus Hagrid"}, new CourseVm{Number = "DARK502", Name = "Defence against dark arts", Instructor ="Severus Snape"}, new CourseVm{Number = "TRAN201", Name = "Transfiguration", Instructor ="Minerva McGonal"} }; var camelCaseFormatter = new JsonSerializerSettings(); camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver(); return JsonConvert.SerializeObject(courses, camelCaseFormatter); }