我在网上找到了几个示例(尤其是在 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 - 内部服务器错误
无法访问请求的页面,因为该页面的相关配置数据无效。
所以看起来我走在正确的轨道上,我只是很难找到一个使用httpErrors
in 的工作示例Web.config
来发送所有 404(甚至所有错误,这对我的需求没有什么影响)到一个动作。