Étant nouveau sur ASP.NET MVC, je me suis interrogé sur la signature des méthodes Controller. Dans tous les exemples que j'ai vus, ils semblent toujours retourner ActionResult, même s'ils retournent réellement une instance ViewResult ou similaire.
Voici un exemple courant:
public ActionResult Index()
{
return this.View();
}
Dans un tel cas, ne serait-il pas plus logique de déclarer la méthode en tant que public ViewResult Index()
, et d'obtenir un support de type plus fort?
L'expérimentation indique que cela fonctionne, donc cela semble possible.
Je me rends compte qu'il peut y avoir des situations où le polymorphisme est souhaité (par exemple si vous souhaitez rediriger uniquement dans certaines situations, mais afficher une vue dans d'autres situations), mais si la méthode toujours renvoie une vue, Je trouverais un ViewResult plus souhaitable.
En termes de compatibilité future, ActionResult fournit évidemment une signature plus robuste, mais si l'on contrôle la base de code entière, il est toujours possible de changer la signature d'une méthode en un type de retour plus général si cela devait devenir nécessaire à l'avenir.
Y a-t-il d'autres considérations dont je ne suis pas au courant ou dois-je simplement déclarer mes méthodes de contrôleur avec des types de retour spécifiques?
Vous pouvez absolument utiliser des types de retour spécifiques, même si la plupart des exemples sur le Web semblent renvoyer le ActionResult . La seule fois où je retournerais la classe ActionResult , c'est lorsque différents chemins de la méthode d'action renvoient différents sous-types.
Steven Sanderson recommande également de renvoyer des types spécifiques dans son livre Pro ASP.NET MVC Framework . Jetez un œil à la citation ci-dessous:
"Cette méthode d'action déclare spécifiquement qu'elle renvoie une instance de ViewResult. Elle fonctionnerait de la même manière si le type de retour de la méthode était ActionResult (la classe de base pour tous les résultats d'action). En fait, certains ASP.NET MVC les programmeurs déclarent toutes leurs méthodes d'action comme renvoyant un ActionResult non spécifique, même s'ils savent avec certitude qu'il renverra toujours une sous-classe particulière. Cependant, c'est un principe bien établi en programmation orientée objet que les méthodes doivent renvoyer le type le plus spécifique possible. (tout en acceptant les types de paramètres les plus généraux possibles). Suivre ce principe maximise la commodité et la flexibilité du code qui appelle votre méthode, comme vos tests unitaires. "
Renvoyez toujours le type le plus précis possible. Vous devez donc renvoyer un ViewResult lorsque l'action affiche toujours une vue. Je n'utiliserais ActionResult que lorsque vous revenez dans ViewResult dans certains cas (données publiées non valides) ou un RedirectToRouteResult dans d'autres cas.
Avec certains scénarios d'actionfiltre/d'exécution avancés, vous pouvez même retourner des choses totalement différentes qui n'ont rien à voir avec ActionResult.
[Réponse partielle]: Vous ne renvoyez pas toujours ActionResult, non. Voici un aperçu rapide de certains autres résultats que vous pouvez renvoyer: http://msdn.Microsoft.com/en-us/library/dd410269%28v=vs.98%29.aspx
Ça va peut-être aider un peu. Bonne chance!
Oui, vous pouvez définir votre action comme: public ViewResult Index()
. Mais parfois, votre action peut renvoyer des résultats différents (c'est impossible sans déclarer result comme base ActionResult
class). Par exemple:
public ActionResult Show()
{
...
if(Request.IsAjaxRequest())
{
return PartialView(...);
}
return View(...);
}
ou:
public ActionResult Show()
{
...
try
{
...
}
catch(Exception)
{
return RedirectToAction(...);
}
return View(...);
}
ActionResult est la classe de base pour les différents types de retour. Votre action doit donc renvoyer un ActionResult ou une classe qui en dérive pour fonctionner. Les plus courants sont ViewResult
, JsonResult
, etc.
Oui, j'ai le livre de Sanderson, et j'ai aimé cette partie sur la spécificité, car c'était quelque chose qui me contrariait quand je regardais d'autres exemples d'action de contrôleur. Ma philosophie, même en apprenant MVC b4, était que, puisque les fonctions (méthodes qui renvoient une valeur) devraient être traitées comme si vous déclariez une variable/être substituable en contexte pour une variable/ref du même type, soyez précis sur le type, comme vous le ferait si déclarer un var (pensez-y comme vouloir éviter de définir toutes vos variables comme type "Object" dans une application - plus robuste, mais vous perdez une vérification au moment du design et la sécurité du type). Facilite également un test unitaire du contrôleur pour le type de retour correct.
Pour une référence connexe, consultez également le principe de substitution de Listkov (le "L" dans "SOLID").