web-dev-qa-db-ja.com

ActionResultではなくJsonResultを使用する場合

この質問に関する具体的な答えを見つけることができませんでした。 this 質問などからの投稿と後続の投稿を表示しましたが、実際に読んだのは、JsonResultにハードコードされたコンテンツタイプがあり、パフォーマンスの向上がまったくないということだけです。

両方の結果がJsonを返すことができる場合、ActionResultではなくJsonResultを使用する必要がある理由.

public ActionResult()
{
    return Json(foo)
}

public JsonResult()
{
    return Json(bar)
}

ActionResultがジョブを完了できず、JsonResultmustを使用するシナリオを誰でも説明できますか。そうでない場合、最初にJsonResultが存在するのはなぜですか。

22
CSharper

JsonResultActionResultを使用する場合

私は通常、具体的な結果を返します(例えば、JsonResultViewResult)、私の長所があります:

このアプローチをサポートするリンクがいくつかあります。

Pro ASP.NET MVC 3 Framework からの引用があります:

注リスト内のアクションメソッドの戻り値の型はViewResultであることに注意してください。より一般的なActionResult型を指定した場合、メソッドはコンパイルおよび動作します。実際、一部のMVCプログラマーは、すべてのアクションメソッドの結果をActionResultとして定義しますが、常により具体的な型を返すことがわかっている場合でもです。各結果タイプをどのように使用できるかを明確にするために、以下の例でこのプラクティスに特に熱心に取り組んでいますが、実際のプロジェクトではよりリラックスする傾向があります。

アクションが異なるタイプの結果を返す必要がある場合にのみ、具体的なものに対してActionResultを使用します。しかし、それは一般的な状況ではありません。

ActionResultは抽象クラスであるため、このタイプのインスタンスを単純に作成して返すことはできません。 JsonResultは具象なので、そのインスタンスを作成してアクションメソッドから戻ることができます。 ActionResultから派生した他の多くのタイプがあります 。基本的にそれらはすべて ExecuteResultメソッドをオーバーライドするために使用 です。

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

このメソッドはControllerActionInvokerによって呼び出され、responseオブジェクトにデータを書き込むロジックを実装します。

ControllerActionInvokerは具体的な結果を知らないため、から派生した結果を処理できます。 ActionResultおよびExecuteResultを実装します。

どちらの場合も、例でJsonResult型のインスタンスを返し、Json(model)JsonResultのインスタンスを作成するファクトリメソッドです。

別のSOの質問があります メソッドのデータ型をできるだけ具体的にするか、より一般的にする方が良いですか? メソッドパラメーターと戻り値のベストプラクティスについて説明します

一般的なアイデアは、抽象型をパラメータとして提供することですより広い範囲のパラメーターを処理します。 クライアントがそれらをキャストまたは変換する必要がないように、具体的な十分な型を返します

18
Ilya Palkin

MVCコントローラーのすべての一般的な戻り値の種類の名前が「結果」で終わることに気づいたかもしれません。ほとんどのアクションはActionResultを返します。 documentation を見ると、いくつかのより特殊化された結果タイプが抽象クラスActionResultを継承していることがわかります。このため、すべてのアクションでActionResultを返すことができ、さまざまなタイプを返すことさえできます。例:

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

これらすべてにより、リクエストに基づいて異なるコンテンツを簡単に返すことができます。それでは、なぜActionResultではなくJsonResultを使用するのでしょうか?おそらく誤解はないので、実際にはonlyだけでJSONを返すことができます。

4
Tobias

それは単純な多態性原則を固守しているだけです。

ActionResultJsonResultViewResult(およびその他)の基本型である抽象ContentResultを返すようにメソッドシグネチャを定義することにより、implementationアクションは、どのActionResultを返すかを決定します。

例えば:

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

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

実際には、OOPでメソッドの戻り値の型をできるだけ抽象的に定義するのが一般的です。Linqの_IEnumerable<>_の使用法も.NET BCLで見つけることができます。例えば:

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

Where()メソッドは_IEnumerable<T>_を返すように宣言されているため、ArrayListHashSetDictionaryなど、_IEnumerable<T>_インターフェイスを実装している任意の型でメソッドを呼び出すことができます。

3
haim770

実際には、JsonResultをActionメソッドの戻り値の型として使用する理由はありません。この場合、抽象クラスActionResultを使用して多態性原則に従うことをお勧めします。

return Json(value)を呼び出すと、実際には次のようなControllerクラスのヘルパーメソッドを呼び出しています。

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

ご覧のとおり-Jsonヘルパーメソッドは、とにかくJsonResultをインスタンス化します。

2
Dmitry Zaets