web-dev-qa-db-ja.com

ASP.NET MVCコントローラーメソッドはActionResultを返す必要がありますか?

ASP.NET MVCが初めてなので、Controllerメソッドのシグネチャについて疑問に思っていました。私が見たすべての例で、実際にViewResultインスタンスなどを返す場合でも、常にActionResultを返すようです。

一般的な例は次のとおりです。

_public ActionResult Index()
{
    return this.View();
}
_

そのような場合、メソッドをpublic ViewResult Index()として宣言し、より強力な型サポートを取得する方が理にかなっていますか?

実験により、これが機能することが示されているため、可能性があります。

多態性が望ましい状況があるかもしれないことを理解しています(たとえば、特定の状況でのみリダイレクトし、他の状況ではビューを表示したい場合)が、メソッドalwaysがビューを返す場合、 ViewResultの方が望ましいと思います。

将来の互換性に関して、ActionResultは明らかにより堅牢なシグネチャを提供しますが、コードベース全体を制御する場合、将来必要になる場合は、メソッドのシグネチャをより一般的な戻り値型に変更することが常に可能です。

私が気付いていない他の考慮事項はありますか、それとも特定の戻り値の型でコントローラーメソッドを宣言する必要がありますか?

56
Mark Seemann

Web上のほとんどの例はActionResultを返すように見えますが、特定の戻り値のタイプを絶対に使用できます。 ActionResultクラスを返すのは、アクションメソッドの異なるパスが異なるサブタイプを返すときだけです。

スティーブン・サンダーソンは、彼の本で特定の型を返すことも推奨しています Pro ASP.NET MVC Framework 。以下の引用を見てください:

」このアクションメソッドは、ViewResultのインスタンスを返すことを明確に宣言します。代わりにメソッドの戻り値のタイプがActionResult(すべてのアクション結果の基本クラス)の場合も同じように動作します。 .NET MVCプログラマーは、特定のサブクラスを常に1つ返すと確信している場合でも、すべてのアクションメソッドを非特定のActionResultを返すと宣言しますが、オブジェクト指向プログラミングでは、メソッドが最も具体的な(可能な限り最も一般的なパラメータータイプを受け入れます。)この原則に従うと、ユニットテストなど、メソッドを呼び出すコードの利便性と柔軟性が最大になります。 "

57
BengtBe

返せる最も正確な型を常に返してください。したがって、アクションが常にビューを表示する場合は、ViewResultを返す必要があります。場合によってはViewResultで(無効な送信データ)を返すとき、または他の場合ではRedirectToRouteResultを返すときにのみActionResultを使用します。

高度なアクションフィルター/実行シナリオを使用すると、ActionResultとは関係のないまったく異なるものを返すこともできます。

13
Paco

[部分的な回答]:常にActionResultを返すとは限りません。返せるその他の結果の概要を以下に示します。 http://msdn.Microsoft.com/en-us/library/dd410269%28v=vs.98%29.aspx

たぶんそれは少し助けになるでしょう。幸運を!

8
Carl

はい、次のようにアクションを定義できます:public ViewResult Index()。ただし、アクションが異なる結果を返す場合があります(結果をベースActionResultクラスとして宣言しないと不可能です)。例えば:

public ActionResult Show()
{
    ...

    if(Request.IsAjaxRequest())
    {
        return PartialView(...);
    }

    return View(...);
}

または:

public ActionResult Show()
{
    ...

    try
    {
        ...
    }
    catch(Exception)
    {
        return RedirectToAction(...);
    }

    return View(...);
}
7
eu-ge-ne

ActionResultは、さまざまな戻り値型の基本クラスです。したがって、動作するには、アクションがActionResult またはそれから派生したクラスを返す必要があります。一般的なものはViewResultJsonResultなどです。

3
GalacticCowboy

うん、サンダーソンの本があります。他のコントローラーのアクションの例を見ていたときに、それが私を悩ませる何かだったので、私はその部分が具体的であることについて好きでした。私の哲学は、MVCを学習するb4でさえ、関数(値を返すメソッド)は変数を宣言している/同じタイプの変数/参照のコンテキストで置換可能であるかのように扱われるべきであるため、 varを宣言する場合(アプリですべての変数を "Object"型として定義するのを避けたいと考えてください-より堅牢ですが、設計時のチェックと型安全性を失います)。正しい戻りタイプのコントローラーユニットテストも容易にします。

関連する参照については、Listkovの代替原則(「SOLID」の「L」)も確認してください。

2
Galaxis