12

現在、から継承するBaseControllerクラスがありSystem.Web.Mvc.Controllerます。そのクラスには、HandleErrorユーザーを「500-おっと、めちゃくちゃにした」ページにリダイレクトする属性があります。これは現在、期待どおりに機能しています。

この作品

<HandleError()> _
Public Class BaseController : Inherits System.Web.Mvc.Controller

''# do stuff
End Class

また、404ページがActionResultごとに機能しており、これも期待どおりに機能しています。

この作品

    Function Details(ByVal id As Integer) As ActionResult
        Dim user As Domain.User = UserService.GetUserByID(id)

        If Not user Is Nothing Then
            Dim userviewmodel As Domain.UserViewModel = New Domain.UserViewModel(user)
            Return View(userviewmodel)
        Else
            ''# Because of RESTful URL's, some people will want to "hunt around"
            ''# for other users by entering numbers into the address.  We need to
            ''# gracefully redirect them to a not found page if the user doesn't
            ''# exist.
            Response.StatusCode = CInt(HttpStatusCode.NotFound)
            Return View("NotFound")
        End If

    End Function

繰り返しますが、これはうまく機能します。ユーザーがhttp://example.com/user/999(userID 999が存在しない場合)のようなものを入力すると、適切な404ページが表示されますが、URLは変更されません(エラーにリダイレクトされません)。ページ)。

このアイデアを機能させることができません

ここで問題が発生します。ユーザーがhttp://example.com/asdf-と入力すると、一般的な404ページに移動します。私がやりたいのは、URLをそのままにして(つまり、他のページにリダイレクトしない)、単に「NotFound」ビューを表示しHttpStatusCode.NotFound、をクライアントにプッシュすることです。

たとえば、https://stackoverflow.com/asdfにアクセスすると、カスタム404ページが表示され、そのままのURLが表示されます。

明らかに私は何かが欠けていますが、それを理解することはできません。「asdf」は実際にはどのコントローラーも指していないので、私の基本コントローラークラスは起動していません。そのため、そこにある「HandleError」フィルターでそれを行うことはできません。

助けてくれてありがとう。

注:ユーザーを404ページにリダイレクトすることは絶対に避けたいです。既存のURLにとどまり、MVCが404VIEWをユーザーにプッシュするようにします。

編集:

私も無駄に次のことを試みました。

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    routes.RouteExistingFiles = False
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
    routes.IgnoreRoute("Assets/{*pathInfo}")
    routes.IgnoreRoute("{*robotstxt}", New With {.robotstxt = "(.*/)?robots.txt(/.*)?"})

    routes.AddCombresRoute("Combres")

    ''# MapRoute allows for a dynamic UserDetails ID
    routes.MapRouteLowercase("UserProfile", _
        "Users/{id}/{slug}", _
        New With {.controller = "Users", .action = "Details", .slug = UrlParameter.Optional}, _
        New With {.id = "\d+"} _
    )


    ''# Default Catch All Valid Routes
    routes.MapRouteLowercase( _
        "Default", _
        "{controller}/{action}/{id}/{slug}", _
        New With {.controller = "Events", .action = "Index", .id = UrlParameter.Optional, .slug = UrlParameter.Optional} _
    )

    ''# Catch All InValid (NotFound) Routes
    routes.MapRoute( _
        "NotFound", _
        "{*url}", _
        New With {.controller = "Error", .action = "NotFound"})

End Sub

私の「NotFound」ルートは何もしていません。

4

6 に答える 6

9

私の他のSOの質問で私の答えを見つけました。解決策を提供してくれたAnh-KietNgoに感謝します。

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

    // A good location for any error logging, otherwise, do it inside of the error controller.

    Response.Clear();
    HttpException httpException = exception as HttpException;
    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "YourErrorController");

    if (httpException != null)
    {
        if (httpException.GetHttpCode() == 404)
        {
            routeData.Values.Add("action", "YourErrorAction");

            // We can pass the exception to the Action as well, something like
            // routeData.Values.Add("error", exception);

            // Clear the error, otherwise, we will always get the default error page.
            Server.ClearError();

            // Call the controller with the route
            IController errorController = new ApplicationName.Controllers.YourErrorController();
            errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
        }
    }
}
于 2010-08-19T21:03:48.173 に答える
3

あなたは試すことができます:

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="~/Error.aspx"/>
</customErrors>

http://msdn.microsoft.com/en-us/library/system.web.configuration.customerrorssection.redirectmode.aspx

RedirectModeプロパティがResponseRewriteに設定されている場合、ユーザーはエラーページに移動し、ブラウザーの元のURLは変更されません。

于 2010-08-19T21:11:21.707 に答える
1

ベースコントローラーにリダイレクトするのではなく、ベースコントローラーで定義されたアクションを返すだけでこれを機能させることができました。

[HandleError]
public ActionResult NotFound()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true;     
    return View("PageNotFound", SearchUtilities.GetPageNotFoundModel(HttpContext.Request.RawUrl));          
}

(「SearchUtilities.GetPageNotFoundModel」ビットは、URLを検索エンジンにフィードすることによって提案を生成することに関するものです)

ベースを継承するアクションメソッドでは、これを簡単に呼び出すことができます。

return NotFound();

...無効なパラメータをキャッチしたときはいつでも。そして、キャッチオールルートも同じです。

于 2011-10-18T10:39:23.867 に答える
1

ルートはパターン一致です。間違ったURLのパターンが以前のルートと一致するため、見つからないルートは機能していません。

それで:

''# Default Catch All Valid Routes
routes.MapRouteLowercase( _
    "Default", _
    "{controller}/{action}/{id}/{slug}", _
    New With {.controller = "Events", .action = "Index", .id = UrlParameter.Optional, .slug = UrlParameter.Optional} _
)

''# Catch All InValid (NotFound) Routes
routes.MapRoute( _
    "NotFound", _
    "{*url}", _
    New With {.controller = "Error", .action = "NotFound"})

http://example.com/asdf-と入力すると、上記の「デフォルト」ルートに一致します-MVCはasdf-Controller検索を実行し、それを見つけることができないため、例外がスローされます。

http://example.com/asdf-/action/id/slug/extraにアクセスすると、「デフォルト」は一致しなくなり、代わりに「NotFound」ルートがたどられます。

既知のすべてのコントローラーのフィルターを「デフォルト」ルートに追加することもできますが、新しいコントローラーを追加するときにそれを維持するのは面倒です。

イベントにフックする必要はまったくありませんがApplication_Error、不足しているコントローラーを回避するためのより良い方法はまだ見つかりませんでした。別の質問として質問しました。

于 2011-04-18T11:14:51.800 に答える
0

ASP.NET MVCフレームワークからの大きなミスは、1つの答えのような「クランチ」なしで404ページをカスタマイズできないためです(実際のカスタマイズとは、1つのエラーページだけではありません)。見つからないすべての原因に対して1つの404エラーを使用するか、[HandleError]を介して複数の500エラーページをカスタマイズできますが、404エラーを宣言的にカスタマイズすることはできません。500エラーはSEOの理由で悪いです。404エラーは適切なエラーです。

于 2010-12-23T08:57:34.940 に答える
0

Web構成で設定します。

<system.web>
      <customErrors mode="On" defaultRedirect="error.html"/>
</system.web>

error.htmlは、ユーザーに任意のHTMLを表示する必要があるカスタムページです。

于 2010-08-07T16:45:42.533 に答える