カスタムASP.NET MVC 404エラーページのルーティング


116

ASP.NET MVCで有効なアクションまたはコントローラーを呼び出さないURLを入力すると、一般的な「リソースが見つかりません」というASP.NETエラーではなく、カスタムHTTP 404エラーページを作成しようとしています。

これを処理するためにweb.configを使用したくありません。

無効なURLをキャッチするために何かできるルーティングマジックはありますか?

更新:与えられた答えを試しましたが、それでも醜い「リソースが見つかりません」というメッセージが表示されます。

別の更新: OK、RC1で明らかに何かが変更されました。私は特に404をトラップすることを試みましたがHttpException、それでも「リソースが見つかりません」ページが表示されます。

私はMvcContribのリソースの機能も何も使用していません-同じ問題。何か案は?



@Peterこれは、アクションが存在しない場合にページが見つからないビューを表示するようにHandleUnknownActionをオーバーライドするとともに、ユーザーが入力する可能性のある他の不思議なことを処理する組み込みのASP.netカスタムエラーハンドラーをオーバーライドすることで追加したソリューションです。 。
dswatik

この作品を@peteだけでなくstackoverflow.com/questions/619895/...
dswatik

8
他のユーザーが気まぐれで、「なぜそれをしたいのですか?これを行うだけです...」などと言うときは嫌ですが、web.configアプローチとそれを使用することを妨げるものがない場合は、あなたのニーズを満たす、それは標準的でエレガントなアプローチです。私の知らない問題が発生する可能性が非常に高いため、そのアプローチに関するフィードバックはありがたいです。
Sean

回答:


10

ルートテーブルの最後にすべてのルートをキャッチして、必要なページを表示するだけです。

参照:ASP.NET MVCの「404ページが見つかりません」クエリを処理するために、すべてのルートをキャッチするにはどうすればよいですか?


私はメッセージ。これは、しかし、私はまだ醜いASP.NETの既定のリソースが見つからない取得しようとした
dswatik

3
私はこの回答にも提供されたリンクにも、この問題の決定的な(そして柔軟な!!)解決策はありません。
ピーター

4
私もそうではありません...これは一種のハックな答えのようです。customErrorsをWebFormsでのように動作させる方法をもっと探しています。何か案は?
JCグラブス

1
これはどちらも機能せず、原則として悪いことです。以前のルーティングパターンのいずれかに一致する不正なURLを検出しないため、機能しません。エラーであるべきものをエラーではないものに変換するため、原理的には悪い。「エラー」という名前のページにリダイレクトすることは、エラーページにリダイレクトすることとは異なります。エラーとして保持し、エラーをログに記録してから、エラーとして処理する必要があります。エラーは貴重な情報です。
マシュー

105

本番サーバーでカスタムエラーを3時間有効にしようとしましたが、ASP.NET MVCでこれを行う方法の最終的な解決策をルートなしで見つけたようです。

ASP.NET MVCアプリケーションでカスタムエラーを有効にするには、次のものが必要です(IIS 7以降):

  1. system.webセクションの下のWeb構成でカスタムページを構成します。

    <customErrors mode="RemoteOnly"  defaultRedirect="~/error">
        <error statusCode="404" redirect="~/error/Error404" />
        <error statusCode="500" redirect="~/error" />
    </customErrors>

    RemoteOnlyローカルネットワークでは実際のエラーが発生することを意味します(開発中に非常に役立ちます)。エラーページのエラーページを書き換えることもできます。

  2. 魔法の応答パラメーターと応答ステータスコードを設定します(エラー処理モジュールまたはエラーハンドル属性内)

      HttpContext.Current.Response.StatusCode = 500;
      HttpContext.Current.Response.TrySkipIisCustomErrors = true;
  3. system.webServerセクションの下のweb configに別の魔法の設定を設定します。

    <httpErrors errorMode="Detailed" />

これは私が見つけた最後のものであり、この後、運用サーバーでカスタムエラーを確認できます。


8
これはまだ理想的な解決策ではありません。適切なHTTP応答コードを取得できません。customErrorsエラーページをロードするためだけに302リダイレクトの結果を使用します。
Justin Helgerson、2014

@ Ek0nomik私は理想的な解決策を見たことがありません:)
Andrew Orsich 2014

2
@JustinHelgersonステータスコードごとにErrorControllerを設定し、それらのアクション内に応答コードを設定し、応答コードを細かく設定します。Fiddlerでテストし、404ステータスコードは404で応答し、500エラーのページは500で応答します。どちらの場合も、カスタムエラービューが表示されます
シェーンノイビル2014

私のチームメイトは、ここここで説明いるように、カスタムエラーページリダイレクトする 500ステータスコードでランタイムエラーを発生させるために、共有フォルダーの下のエラービューを削除ました。希望は誰かを助けます。
shaijut

41

この記事のビューを返すErrorControllerを作成して、エラー処理を機能させました。また、global.asaxのルートに「Catch All」を追加する必要がありました。

Web.config ..にない場合、これらのエラーページにどのように到達するかわかりません。私のWeb.configは以下を指定する必要がありました:

customErrors mode="On" defaultRedirect="~/Error/Unknown"

それから私も追加しました:

error statusCode="404" redirect="~/Error/NotFound"

2
ありがとう-それは私を助けました、2年後!404のカスタムエラーのみが必要な場合はどうしますか?
Shaul Behr 2011

1
@Shaulもう1年後... defaultRedirectを設定しないで、属性を完全に除外します。
NJE 2012年

27

ソース

NotFoundMVC-ASP.NET MVC3アプリケーションでコントローラー、アクション、またはルートが見つからない場合は常に、使いやすい404ページを提供します。デフォルトのASP.NETエラーページの代わりにNotFoundというビューがレンダリングされます。

このプラグインはnugetを使用して追加できます。Install-PackageNotFoundMvc

NotFoundMvcは、Webアプリケーションの起動時に自動的にインストールされます。これは、404 HttpExceptionが通常ASP.NET MVCによってスローされるすべての異なる方法を処理します。これには、欠落しているコントローラー、アクション、および経路が含まれます。

ステップバイステップインストールガイド:

1-プロジェクトを右クリックし、[Nugetパッケージの管理...]を選択します。

2-検索しNotFoundMvcてインストールします。 ここに画像の説明を入力してください

3-インストールが完了すると、2つのファイルがプロジェクトに追加されます。以下のスクリーンショットに示すように。

ここに画像の説明を入力してください

4-Views / Sharedにある新しく追加されたNotFound.cshtmlを開き、自由に変更します。次に、アプリケーションを実行し、誤ったURLを入力すると、ユーザーフレンドリーな404ページが表示されます。

ここに画像の説明を入力してください

これ以上、ユーザーは次のようなエラーメッセージを受け取ります Server Error in '/' Application. The resource cannot be found.

お役に立てれば :)

PS:Andrew Daveyがこのような素晴らしいプラグインを作成してくれたことに感謝します。


@niicoソースコードを見ると、応答コードが404に設定されているようです。そうです。
ウィルディーン

20

IISエラーページを置き換えるには、web.configでこれを試してください。これは私が推測する最良の解決策であり、正しいステータスコードも送信します。

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="404" path="Error404.html" responseMode="File" />
    <error statusCode="500" path="Error.html" responseMode="File" />
  </httpErrors>
</system.webServer>

Tipilaからの詳細情報-カスタムエラーページの使用ASP.NET MVC


1
+1。これは、複数の領域を持つMVC5で私にとって一貫して機能するように思われた唯一のものです。
hawkke 2014

これが最も簡単な解決策です。ただし、エラーページでかみそり構文を使用することはできません。
ハイエース2016年

15

このソリューションでは、web.configファイルの変更やキャッチオールルートは必要ありません。

まず、このようなコントローラーを作成します。

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Regular Error";
        return View();
    }

    public ActionResult NotFound404()
    {
        ViewBag.Title = "Error 404 - File not Found";
        return View("Index");
    }
}

次に、「Views / Error / Index.cshtml」の下にビューを作成します。

 @{
      Layout = "~/Views/Shared/_Layout.cshtml";
  }                     
  <p>We're sorry, page you're looking for is, sadly, not here.</p>

次に、以下のようにグローバルasaxファイルに以下を追加します。

protected void Application_Error(object sender, EventArgs e)
{
        // Do whatever you want to do with the error

        //Show the custom error page...
        Server.ClearError(); 
        var routeData = new RouteData();
        routeData.Values["controller"] = "Error";

        if ((Context.Server.GetLastError() is HttpException) && ((Context.Server.GetLastError() as HttpException).GetHttpCode() != 404))
        {
            routeData.Values["action"] = "Index";
        }
        else
        {
            // Handle 404 error and response code
            Response.StatusCode = 404;
            routeData.Values["action"] = "NotFound404";
        } 
        Response.TrySkipIisCustomErrors = true; // If you are using IIS7, have this line
        IController errorsController = new ErrorController();
        HttpContextWrapper wrapper = new HttpContextWrapper(Context);
        var rc = new System.Web.Routing.RequestContext(wrapper, routeData);
        errorsController.Execute(rc);

        Response.End();
}

これを行ってもカスタムIISエラーページが表示される場合は、Web構成ファイルで以下のセクションがコメント化されている(または空になっている)ことを確認してください。

<system.web>
   <customErrors mode="Off" />
</system.web>
<system.webServer>   
   <httpErrors>     
   </httpErrors>
</system.webServer>

404は多くの場合Webサーバーによってインターセプトされ、アプリケーションレベルでは処理されないため、このアプローチがすべてのインスタンスで機能するとは思いません。
Chris Halcrow、2016

このアプローチを使用する場合Response.End();は、Application_Errorハンドラーの最後にを追加することをお勧めします。これがないと、特定のセッションで最初に発生したエラーのみがトリガーされます。これは、たとえば、Application_Errorハンドラーにカスタムエラーロギングがある場合に問題になります。
キース

6

あなたはMVC 4で作業する場合は、あなたが見ることができ、これをソリューションます。

次のApplication_Errorメソッドをmyに追加しますGlobal.asax

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Index");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    IController controller = new ErrorController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();

コントローラ自体は本当にシンプルです:

public class ErrorController : Controller
{
    public ActionResult Index(int statusCode, Exception exception)
    {
        Response.StatusCode = statusCode;
        return View();
    }
}

GitHubMvc4CustomErrorPageの完全なソースコードを確認してください


0

私は同じ問題を抱えていました、あなたがしなければならないことは、viewsフォルダのweb.configファイルにcustomErrors属性を追加する代わりに、プロジェクトのルートフォルダのweb.configファイルにそれを追加する必要があることです


0

エラーページを1か所で完全にカスタマイズできる真の答えは次のとおりです。web.configを変更したり、別のコードを作成したりする必要はありません。

MVC 5でも機能します。

このコードをコントローラーに追加します。

        if (bad) {
            Response.Clear();
            Response.TrySkipIisCustomErrors = true;
            Response.Write(product + I(" Toodet pole"));
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            //Response.ContentType = "text/html; charset=utf-8";
            Response.End();
            return null;
        }

http://www.eidias.com/blog/2014/7/2/mvc-custom-error-pagesに基づく


0

特定のケースについて話します

以下のようにHomeControllerで「PageNotFoundメソッド」を使用している場合

[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

これは機能しません。ただし、以下のようにルートタグをクリアする必要があります。

//[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

そして、それをweb.configのメソッド名として変更すると、機能します。 ただし、web.configで以下のようなコードを実行することを忘れないでください

<customErrors mode="On">
  <error statusCode="404" redirect="~/PageNotFound" /> 
 *// it is not "~/404" because it is not accepted url in Route Tag like [Route("404")]*
</customErrors>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.