web-dev-qa-db-ja.com

ASP.NET MVC-すべてのルートとデフォルトルートをキャッチ

アプリケーションに404エラーを正しく生成させるために、以下に示すように、ルートテーブルの最後にcatch allルートを実装しました。

 routes.MapRoute(
            "NotFound", _
           "{*url}", _
           New With {.controller = "Error", .action = "PageNotFound"} _
       )

ただし、これを機能させるには、デフォルトルートを削除する必要がありました。

{controller}/action/{id}

しかし、デフォルトが削除されたため、アクションリンクのほとんどは機能しなくなり、それらを再び機能させる唯一の方法は、各コントローラー/アクションに個別のルートを追加することです。

各コントローラー/アクションのルートを追加するのではなく、これを行う簡単な方法はありますか?

ユーザーが不明なルートにナビゲートしようとした場合、キャッチオールルートが機能するデフォルトルートを作成することは可能ですか?

67
Sean Taylor

ルート制約を使用する

あなたの場合、デフォルトルートを定義する必要があります{controller}/{action}/{id}そして、それに制約を置きます。おそらくコントローラー名またはアクションに関連しています。その後、キャッチを1つずつ入れて、問題なく動作するはずです。

そのため、誰かが制約に失敗したリソースを要求すると、キャッチオールルートは要求に一致します。

そう。最初にルート制約を使用してデフォルトルートを定義し、次にその後のすべてのルートをキャッチします。

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { controller = "Home|Settings|General|..." } // this is basically a regular expression
);
routes.MapRoute(
    "NotFound",
    "{*url}",
    new { controller = "Error", action = "PageNotFound" }
);
102
Robert Koritnik
//this catches all  requests
routes.MapRoute(
    "Error",
    "{*.}",
     new { controller = "PublicDisplay", action = "Error404" } 
);

ルートテーブルの最後にこのルートを追加します

19
Praveen Prasad

ああ、問題はデフォルトのルートキャッチセグメントURLすべてです。ここでの問題は、リクエストを誰が処理するかを決定する前にルーティングが実行されることです。したがって、3つのセグメントのURLは、後で処理するコントローラーがないために後で終了した場合でも、デフォルトルートと一致します。

できることの1つは、コントローラーでHa​​ndleMissingActionメソッドをオーバーライドすることです。また、タグを使用してすべての404の問題をキャッチする必要があります。

7
Haacked

さて、私が見つけたのは、これを行う良い方法がないということです。 redirectModecustomErrorsプロパティをResponseRewriteに設定しました。

<customErrors mode="On" defaultRedirect="~/Shared/Error" redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="~/Shared/PageNotFound"/>
</customErrors>

これにより、求められている動作が得られますが、フォーマットされたページは表示されません。

私にとって、SEOに関する限り、これは不十分です。しかし、SOはまさに私がやりたいことをするので、私は行方不明になっている解決策があると感じます。URLは失敗したページに残り、404をスローします。 Firebug。

2
Dustin Laine

これを最も読みやすいバージョンとしてお勧めします。 RouteConfig.csでこれが必要です。また、アクション「PageNotFound」を含むErrorController.csというコントローラーが必要です。これにより、ビューを返すことができます。 PageNotFound.cshtmlを作成すると、404への応答として返されます。

        routes.MapRoute(
            name:  "PageNotFound",
            url:  "{*url}",
            defaults: new { controller = "Error", action = "PageNotFound" }
        );

これの読み方:

name: "PageNotFound"

=任意の名前「PageNotFound」で新しいルートテンプレートを作成します

url:"{*url}"

=このテンプレートを使用して、未処理のルートをすべてマッピングします

defaults: new { controller = "Error", action = "PageNotFound" }

=不正なパスがマップするアクションを定義します(エラーコントローラーの 'PageNotFound'アクションメソッド)。間違って入力されたパスは明らかにアクションメソッドにマッピングされないため、これが必要です。

1
Chris Halcrow

ASP.NET Coreを探している場合は、すべてのルートをキャッチし、Googleでasp.net core catch all routeはあなたをここに連れてきます:

ASP.netコアMVCはすべてのルートサーブ静的ファイルをキャッチ

0
Ostati

設定のセクションで404エラードキュメントを設定し、デフォルトルートを復元する方がおそらく良いでしょう。

FWIW、デフォルトのルート要件も遅れていると思います。

0
Wyatt Barnett

私のソリューションは2つのステップです。

Global.asax.csファイルにこの関数を追加することで、最初にこの問題を解決しました。

protected void Application_Error(Object sender, EventArgs e)

Server.GetLastError()をHttpExceptionにキャストして、GetHttpCodeをチェックしました。このソリューションの詳細は次のとおりです。

ASP.NET MVCカスタムエラー処理Application_Error Global.asax?

これは、コードを取得した元のソースではありません。ただし、これは既にルーティングされた404エラーのみをキャッチします。私の場合、それは任意の2レベルのURLです。

たとえば、これらのURLは404ページを表示します。

www.site.com/blah

www.site.com/blah/blah

ただし、www.site.com/blah/blah/blahは単にページが見つからなかったと言うだけです。私の他のすべてのルートの後にキャッチオールルートを追加すると、これが解決しました:

routes.MapRoute(
            "NotFound",
            "{*url}",
            new { controller = "Errors", action = "Http404" }
        );

ただし、NotFoundルートはファイル拡張子を持つリクエストをルーティングしないようです。これは、異なるルートでキャプチャされた場合に機能します。

0
Marcus10110