2014-10-15 6 views
18

zu verwenden Ich konnte keine konkrete Antwort zu dieser Frage finden. Ich habe Beiträge und nachfolgende Beiträge von this Frage und anderswo gesehen, aber alles, was ich wirklich aus dem Lesen gekommen bin, ist, dass JsonResult einen hardcoded Inhaltstyp hat und es wirklich keine Leistungssteigerungen gibt.Wann JsonResult über ActionResult

Wenn beide Ergebnisse Json zurückgeben können, warum würden Sie benötigen, um JsonResult über ActionResult zu verwenden.

public ActionResult() 
{ 
    return Json(foo) 
} 

public JsonResult() 
{ 
    return Json(bar) 
} 

Kann jemand ein Szenario erklären, wo Action einfach nicht die Aufgabe und JsonResult muss getan erhalten können verwendet werden. Wenn nicht, warum existiert JsonResult überhaupt?

Antwort

13

Wann verwendet JsonResult über ActionResult

ich in der Regel konkrete Ergebnisse liefern (zB JsonResult, ViewResult), und es sind meine Profis:

Es gibt einige Links, wo die Menschen diesen Ansatz unterstützen:

Es ist ein Zitat von Pro ASP.NET MVC 3 Framework:

Hinweis Beachten Sie, dass der Rückgabetyp für die Aktionsmethode in der -Liste lautet. Die Methode würde genauso kompilieren und funktionieren , wenn wir den allgemeineren ActionResult Typ angegeben hätten. In der Tat, einige MVC Programmierer definieren das Ergebnis jeder Aktionsmethode als ActionResult, auch wenn sie wissen, dass es immer einen mehr spezifischen Typ zurückgeben wird. Wir waren besonders fleißig in dieser Praxis in die folgenden Beispiele, um klar zu machen, wie Sie jedes Ergebnis Art verwenden können, aber wir neigen dazu, in realen Projekten entspannter zu sein.

würde ich ActionResult über Beton eine nur verwenden, wenn eine Aktion verschiedene Arten von Ergebnissen zurückgeben sollte. Aber es ist nicht diese allgemeine Situation.

Ich möchte auch hinzufügen, dass ActionResult eine abstrakte Klasse ist, so dass Sie nicht einfach eine Instanz dieses Typs erstellen und zurückgeben können. JsonResult ist konkret, so dass Sie seine Instanz erstellen und von einer Aktionsmethode zurückkehren können. There are many other types that derived from ActionResult und im Grunde alle von ihnen sind used to override ExecuteResult method.

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

Diese Methode wird von ControllerActionInvoker aufgerufen und implementiert Datenlogik zum Schreiben response Objekt.

ControllerActionInvoker weiß nichts über konkrete Ergebnisse, so dass es kein Ergebnis verarbeiten kann, die von ActionResult abgeleitet und implementiert ExecuteResult.

In beiden Fällen geben Sie in Ihrem Beispiel eine Instanz des Typs JsonResult zurück, und Json(model) ist einfach eine Factory-Methode, die eine Instanz von JsonResult erstellt.

Es gibt noch eine SO Frage Is it better to have a method's datatype be as specific as possible or more general? wo Best Practices für Methodenparameter und Rückgabewerte diskutiert werden.

Die allgemeine Idee ist als abstrakten Typen bereitstellt Parameter, so dass Ihre Methode breitere Palette von Parametern verarbeiten kann; Zurückgeben von Beton genug Typen, so dass Ihre Kunden nicht umwandeln oder konvertieren müssen.

4

Sie haben vielleicht bemerkt, dass die Namen aller gebräuchlichen Rückgabetypen in einem MVC-Controller mit "result" enden, und meistens geben die meisten Aktionen ein ActionResult zurück. Wenn Sie sich die documentation ansehen, können Sie sehen, dass mehrere, mehr spezifizierte Ergebnistypen von der abstrakten Klasse ActionResult erben. Aus diesem Grund können Sie jetzt ActionResult in allen Ihren Aktionen zurückgeben und sogar unterschiedliche Typen zurückgeben. Beispiel:

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

All dies macht es einfacher, verschiedene Inhalte, basierend auf der Anfrage, zurückzugeben. Warum sollten Sie JsonResult über ActionResult verwenden? Vielleicht gibt es also keine Missverständnisse, und Sie können tatsächlich nur JSON, vielleicht für die Lesbarkeit, oder eine andere persönliche Vorliebe zurückgeben.

2

Eigentlich gibt es keine Gründe, JsonResult als Rückgabetyp von Aktionsmethoden zu verwenden. In diesem Fall ist es besser, die abstrakte Klasse ActionResult zu verwenden, um polymorphe Prinzipien zu befolgen.

von return Json(value) Aufruf Sie tatsächlich Aufruf Hilfsmethode der Controller-Klasse sind, die wie folgt aussieht:

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

Wie wir sehen können - Json Hilfsmethode es JsonResult sowieso instanziiert.

2

Es ist nur einfach haften Polymorphismus Prinzip.

Durch die Definition der Methodensignatur als ein abstraktes ActionResult Rückkehr das ist der Basistyp für JsonResult, ViewResult, ContentResult (und andere) haben Sie die Möglichkeit gegeben sind eine der oben genannten Typen zurückzukehren, indem man die Umsetzung der Aktion entscheiden, welche ActionResult zurückgeben.

Zum Beispiel:

public ActionResult GetData(int id) 
{ 
    var data = .... // some data 

    if (Request.AcceptTypes.Contains("json")) 
      return Json(data); 
    else 
      return View(data); 
} 

Es ist tatsächlich eine gängige Praxis in OOP die zurückgegebenen Art des Verfahrens, wie abstrakten wie möglich zu definieren. Sie können es finden in.NET BCL als auch die IEnumerable<> Verwendung in Linq zum Beispiel:

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

Die Where() Methode wird als erklärt IEnumerable<T> Rückkehr, so dass Sie die Methode auf jede Art aufrufen kann, die die IEnumerable<T> Schnittstelle implementiert, sei es ein Array, List, HashSet oder Dictionary.