2

我在网上找到了几个示例(尤其是在 StackOverflow 上),用于在 ASP.NET MVC 中创建一个包罗万象的路由,但这在 MVC4 中似乎对我不起作用:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("elfinder.connector");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );

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

}

控制器动作定义为:

    public ActionResult CatchAll(string url)
    {
        // catch the URL and use it for something
    }

这里的目标是拦截所有潜在的 404 错误,并根据 URL 响应 404 或其他内容。但是,我从来没有结束过这个CatchAll动作,我只是得到一个默认的 404 URL,比如:

  • ~/foo
  • ~/this/is/a/test/url

我在这里做错了吗?我想避免必须捕获错误Application_Error,如果是 404,请从那里重新转发。只是看起来有点乱。在我看来,处理这些请求的正确方法是将它们简单地路由到正确的操作,不是吗?

更新:虽然我的 URL 纯粹主义者希望避免使用Response.Redirect,但我目前正在尝试将以下内容作为请求的全局包罗万象:

protected void Application_Error()
{
    Exception exception = Server.GetLastError();
    HttpException httpException = exception as HttpException;

    if (httpException != null)
        if (httpException.GetHttpCode() == 404)
        {
            Server.ClearError();
            Response.Redirect(String.Format("~/Home/CatchAll/?url={0}", Request.Path));
        }
}

但是,这仅在 URL 的结构与路由匹配时才有效。否则看起来 IIS 甚至没有将请求发送到应用程序,它只是直接返回 404。我几乎需要一个全局处理程序,其中任何未映射到操作的网站请求的 URL 都会被定向。

更新:看起来两件事的结合应该对我有用。首先,捕获 404 Application_Error(或者Application_EndRequest正如某些人所建议的,无论哪种方式都可以满足我的需要)涵盖了与路由结构匹配但未找到操作的任何内容。但是,仍然存在与路由结构不匹配的请求的情况。

由于各种原因,我不想为此调整 IIS。解决方案应包含在应用程序本身中。幸运的是,我可以保证最新的 .NET 和 IIS,这允许我使用Web.config设置来指导 IIS 如何处理错误。所以我目前正在尝试这个:

<httpErrors errorMode="Custom" defaultResponseMode="Redirect" defaultPath="/Home/CatchAll">
  <clear/>
</httpErrors>

然而,这似乎并不完全正确。它正在影响 IIS,因为错误响应已更改,但它仍然是错误响应。这是:

HTTP 错误 500.19 - 内部服务器错误

无法访问请求的页面,因为该页面的相关配置数据无效。

所以看起来我走在正确的轨道上,我只是很难找到一个使用httpErrorsin 的工作示例Web.config来发送所有 404(甚至所有错误,这对我的需求没有什么影响)到一个动作。

4

0 回答 0