net mvc jsonrequestbehavior data asp c# asp.net-mvc json asp.net-mvc-4 return-value

c# - jsonrequestbehavior - return json mvc 5



Cuándo usar JsonResult sobre ActionResult (4)

Cuándo usar JsonResult sobre ActionResult

Por lo general, devuelvo resultados concretos (por ejemplo, ViewResult , ViewResult ) y existen mis ventajas:

Hay algunos enlaces donde las personas apoyan este enfoque:

Hay una cita de Pro ASP.NET MVC 3 Framework :

Nota Tenga en cuenta que el tipo de retorno para el método de acción en el listado es ViewResult . El método se compilaría y funcionaría igual de bien si hubiéramos especificado el tipo más general de ActionResult . De hecho, algunos programadores de MVC definirán el resultado de cada método de acción como ActionResult , incluso cuando saben que siempre devolverá un tipo más específico. Hemos sido particularmente diligentes en esta práctica en los ejemplos que siguen para aclarar cómo puede usar cada tipo de resultado, pero tendemos a ser más relajados en proyectos reales.

ActionResult sobre uno concreto solo si una acción debe devolver diferentes tipos de resultados. Pero no es esa situación común.

También me gustaría agregar que ActionResult es una clase abstracta, por lo que no puede simplemente crear una instancia de este tipo y devolverla. JsonResult es concreto, por lo que puede crear su instancia y regresar de un método de acción. Hay muchos otros tipos que se derivan de ActionResult y básicamente todos ellos se utilizan para anular el método ExecuteResult .

public abstract class ActionResult { public abstract void ExecuteResult(ControllerContext context); }

ControllerActionInvoker invoca este método e implementa la escritura lógica de datos en el objeto de response .

ControllerActionInvoker no conoce los resultados concretos, por lo que puede manejar cualquier resultado derivado de ActionResult e implementa ExecuteResult .

En ambos casos, devuelve una instancia del tipo JsonResult en su ejemplo y Json(model) es simplemente un método de fábrica que crea una instancia de JsonResult .

Hay otra pregunta de SO ¿Es mejor que el tipo de datos de un método sea lo más específico posible o más general? donde se discuten las mejores prácticas para parámetros de método y valores de retorno .

La idea general es proporcionar tipos abstractos como parámetros para que su método pueda manejar un rango más amplio de parámetros; devolver tipos suficientemente concretos para que sus clientes no tengan que lanzarlos o convertirlos.

No he podido encontrar una respuesta concreta con respecto a esta pregunta. He visto publicaciones y publicaciones posteriores de this pregunta y en otros lugares, pero todo lo que realmente he leído es que JsonResult tiene un tipo de contenido codificado y realmente no hay ningún aumento de rendimiento.

Si ambos resultados pueden devolver a Json, ¿por qué necesitaría usar JsonResult sobre ActionResult?

public ActionResult() { return Json(foo) } public JsonResult() { return Json(bar) }

¿Alguien puede explicar un escenario donde ActionResult simplemente no puede hacer el trabajo y se debe usar JsonResult? Si no es así, ¿por qué JsonResult existe en primer lugar?


Es posible que haya notado que los nombres de todos los tipos de devolución comunes en un controlador MVC terminan con "resultado" y, en la mayoría de los casos, la mayoría de las acciones devuelven un ActionResult. Si observa la documentation , puede ver que varios tipos de resultados, más especalizados, heredan de la clase abstracta ActionResult. Debido a esto, ahora puede devolver un ActionResult en todas sus acciones, e incluso devolver diferentes tipos. Ejemplo:

public ActionResult View(int id) { var result = _repository.Find(id); if(result == null) return HttpNotFound(); //HttpNotFoundResult, which inherits from HttpStatusCodeResult return View(result); //ViewResult }

Todo esto hace que sea más fácil devolver contenido diferente, según la solicitud. Entonces, ¿por qué usarías JsonResult sobre ActionResult? Tal vez no haya malentendidos, y de hecho solo puede devolver JSON, quizás por legibilidad, o alguna otra preferencia personal.


Simplemente se adhiere al principio del polimorfismo simple.

Al definir la firma del método como devolver un ActionResult abstracto, que es el tipo base para JsonResult , ViewResult , ContentResult (y otros), se le permite devolver cualquiera de los tipos anteriores permitiendo que la implementación de la acción decida qué ActionResult devolver .

Por ejemplo:

public ActionResult GetData(int id) { var data = .... // some data if (Request.AcceptTypes.Contains("json")) return Json(data); else return View(data); }

En realidad, es una práctica común en OOP definir el tipo devuelto del método lo más abstracto posible. También puede encontrarlo en .NET BCL, el uso de IEnumerable<> en Linq, por ejemplo:

public static IEnumerable<T> Where<T> ( this IEnumerable<T> source, Func<T, bool> predicate );

El método Where() se declara que devuelve IEnumerable<T> para que pueda llamar al método en cualquier tipo que esté implementando la IEnumerable<T> , ya sea una Array , List , HashSet o Dictionary .


En realidad, no hay razones para usar JsonResult como tipo de retorno de métodos de acción. En este caso, es mejor usar la clase abstracta ActionResult para seguir los principios polimórficos.

Al llamar a return Json(value) , en realidad está llamando al método auxiliar de la clase Controller que se ve así:

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

Como podemos ver, el método de ayuda de JsonResult instancia a JsonResult todos modos.