net negotiation mvc frombody formatters content asp asp.net-mvc json asp.net-mvc-3 serialization

asp.net-mvc - mvc - content negotiation in web api



Cambiar el serializador JSON predeterminado usado en ASP MVC3 (2)

Estoy agregando esta respuesta simplemente porque estoy usando una solución alternativa que no requiere reemplazar la clase System.Web.Mvc.Controller. Agrego los siguientes métodos de extensión a la clase System.Web.Mvc.Controller. El único "beneficio" de esta solución es que no requiere que cambie la clase base de las clases de controlador generadas por el código. De lo contrario, es funcionalmente equivalente a la respuesta aceptada.

public static JsonResult ToJsonResult(this Controller controller, object target, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { if (target != null) { if (target.GetType().HasAttribute<DataContractAttribute>()) { return new DataContractJsonResult() { ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior, Data = target }; } } return new JsonResult() { ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior, Data = target }; } public static JsonResult ToJsonResult(this Controller controller, object target) { return controller.ToJsonResult(target, null, null, JsonRequestBehavior.DenyGet); } public static JsonResult ToJsonResult(this Controller controller, object target, string contentType) { return controller.ToJsonResult(target, contentType, null, JsonRequestBehavior.DenyGet); } public static JsonResult ToJsonResult(this Controller controller, object target, string contentType, Encoding contentEncoding) { return controller.ToJsonResult(target, contentType, contentEncoding, JsonRequestBehavior.DenyGet); } public static JsonResult ToJsonResult(this Controller controller, object target, string contentType, JsonRequestBehavior behavior) { return controller.ToJsonResult(target, contentType, null, behavior); }

En mi aplicación, anulo el controlador predeterminado y uso el serializador JSON.NET si el tipo tiene el atributo DataContract. Esta funcionalidad está encapsulada en la clase DataContractJsonResult, que no está incluida, pero se modela después de la clase en la respuesta aceptada a esta pregunta.

Esta pregunta ya tiene una respuesta aquí:

Tengo un controlador que devuelve grandes objetos JSON a jQuery Flot y me preguntaba qué tan fácil sería reemplazar el JavaScriptSerializer predeterminado con algo más rápido como el de ServiceStack.Text.

Sería bueno si pudiera cambiar este tipo de cosas utilizando DependencyResolver, pero supongo que si todo se resolviera, podría ser bastante lento.


su mejor apuesta es heredar de la clase JsonResult y anular el método Execute como

public class CustomJsonResult: JsonResult { public CustomJsonResult() { JsonRequestBehavior = JsonRequestBehavior.DenyGet; } 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) { CustomJsSerializer serializer = new CustomJsSerializer(); response.Write(serializer.Serialize(Data)); } } }

el código se toma de la clase JsonResult de mvc3 y cambió esta línea

JavaScriptSerializer serializer = new JavaScriptSerializer();

a

CustomJsSerializer serializer = new CustomJsSerializer();

Puedes usar esta clase en método de acción como

public JsonResult result() { var model = GetModel(); return new CustomJsonResult{Data = model}; }

Además, puede anular el método json de la clase Controller en su controlador Base como

public class BaseController:Controller { protected internal override JsonResult Json(object data) { return new CustomJsonResult { Data = data }; } }

Ahora, si tiene todos sus controladores de BaseController, return Json(data) a su esquema de serialización. También hay otras sobrecargas del método Json que puede optar por anular.