Je n'ai pas pu trouver de réponse concrète à cette question. J'ai vu les messages et les messages suivants de this question et ailleurs, mais tout ce que je retiens de la lecture est que JsonResult a un type de contenu codé en dur et qu'il n'y a vraiment aucun gain de performances.
Si les deux résultats peuvent renvoyer Json, pourquoi auriez-vous besoin d'utiliser JsonResult plutôt que ActionResult.
public ActionResult()
{
return Json(foo)
}
public JsonResult()
{
return Json(bar)
}
Quelqu'un peut-il expliquer un scénario où ActionResult ne peut tout simplement pas faire le travail et JsonResult doit être utilisé. Sinon, pourquoi JsonResult existe-t-il en premier lieu.
Quand utiliser
JsonResult
surActionResult
Je retourne généralement des résultats concrets (par exemple JsonResult
, ViewResult
) et il y a mes avantages:
PartialViewResult
et ViewResult
comme type de résultat avec précision.Il existe des liens où les gens soutiennent cette approche:
Il y a une citation de Pro ASP.NET MVC 3 Framework :
Remarque Notez que le type de retour pour la méthode d'action dans la liste est
ViewResult
. La méthode se compilerait et fonctionnerait aussi bien si nous avions spécifié le type plus généralActionResult
. En fait, certains programmeurs MVC définiront le résultat de chaque méthode d'action commeActionResult
, même lorsqu'ils savent qu'il renverra toujours un type plus spécifique. Nous avons été particulièrement diligents dans cette pratique dans les exemples qui suivent pour montrer clairement comment vous pouvez utiliser chaque type de résultat, mais nous avons tendance à être plus détendus dans les projets réels.
J'utiliserais ActionResult
par rapport à une action concrète uniquement si une action devait renvoyer différents types de résultats. Mais ce n'est pas cette situation courante.
Je voudrais également ajouter que ActionResult
est une classe abstraite, vous ne pouvez donc pas simplement créer une instance de ce type et la renvoyer. JsonResult
est concret, vous pouvez donc créer son instance et revenir d'une méthode d'action. Il existe de nombreux autres types dérivés de ActionResult
et essentiellement tous sont tilisés pour remplacer la méthode ExecuteResult
.
public abstract class ActionResult
{
public abstract void ExecuteResult(ControllerContext context);
}
Cette méthode est invoquée par ControllerActionInvoker
et implémente la logique d'écriture des données dans l'objet response
.
ControllerActionInvoker
ne connaît pas les résultats concrets afin qu'il puisse gérer tout résultat dérivé de ActionResult
et implémente ExecuteResult
.
Dans les deux cas, vous retournez une instance de type JsonResult
dans votre exemple et Json(model)
c'est simplement une méthode d'usine qui crée une instance de JsonResult
.
Il y a une autre question SO Est-il préférable que le type de données d'une méthode soit aussi spécifique que possible ou plus général? où les meilleures pratiques pour les paramètres de méthode et les valeurs de retour sont discutées .
L'idée générale est de fournir des types abstraits comme paramètres afin que votre méthode puisse gérer une plus large gamme de paramètres; renvoyant suffisamment de types concrets pour que vos clients n'aient pas besoin de les convertir ou de les convertir.
Vous avez peut-être remarqué que les noms de tous les types de retour courants dans un contrôleur MVC se terminent par "résultat" et, le plus souvent, la plupart des actions renvoient un ActionResult. Si vous regardez la documentation , vous pouvez voir que plusieurs types de résultats, plus spécifiques, héritent de la classe abstraite ActionResult. Pour cette raison, vous pouvez maintenant renvoyer un ActionResult dans toutes vos actions, et même renvoyer différents types. Exemple:
public ActionResult View(int id)
{
var result = _repository.Find(id);
if(result == null)
return HttpNotFound(); //HttpNotFoundResult, which inherits from HttpStatusCodeResult
return View(result); //ViewResult
}
Tout cela facilite le retour de contenu différent, en fonction de la demande. Alors pourquoi utiliseriez-vous JsonResult plutôt que ActionResult? Peut-être qu'il n'y a donc pas de malentendus, et vous en effet seulement pouvez retourner JSON, peut-être pour la lisibilité, ou une autre préférence personnelle.
Il adhère simplement au principe Polymorphisme.
En définissant la signature de méthode comme renvoyant un résumé ActionResult
qui est le type de base pour JsonResult
, ViewResult
, ContentResult
(et autres), vous obtenez le possibilité de renvoyer l'un des types ci-dessus en laissant le implémentation de l'action décider quel ActionResult
retourner.
Par exemple:
public ActionResult GetData(int id)
{
var data = .... // some data
if (Request.AcceptTypes.Contains("json"))
return Json(data);
else
return View(data);
}
Il s'agit en fait d'une pratique courante dans OOP pour définir le type renvoyé de la méthode aussi abstrait que possible. Vous pouvez également le trouver dans .NET BCL, l'utilisation de IEnumerable<>
Dans Linq par exemple:
public static IEnumerable<T> Where<T>
(
this IEnumerable<T> source,
Func<T, bool> predicate
);
La méthode Where()
est déclarée comme retournant IEnumerable<T>
Afin que vous puissiez appeler la méthode sur n'importe quel type qui implémente l'interface IEnumerable<T>
, Que ce soit un Array
, List
, HashSet
ou Dictionary
.
En fait, il n'y a aucune raison d'utiliser JsonResult
comme type de retour des méthodes Action. Dans ce cas, il est préférable d'utiliser la classe abstraite ActionResult
pour suivre les principes polymorphes.
En appelant return Json(value)
vous appelez en fait la méthode d'assistance de la classe Controller qui ressemble à:
protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
return new JsonResult
{
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior
};
}
Comme nous pouvons le voir - Json
méthode d'assistance, elle instancie JsonResult
de toute façon.