asp.net-mvc - 更正缺少 ASP.Net MVC Controller 的 404 消息

标签 asp.net-mvc asp.net-mvc-2 routing asp.net-mvc-routing

我有一个 MVC 2 应用程序,它应该总是提供一个“不错”的 404 页面。

但是目前我得到一个低级别的 .Net:“'/sitename' 应用程序中的服务器错误...”

我有一个基本 Controller ,它有一个 NotFound Action ,可以呈现漂亮的 404 页面。

处理缺失的 Action :

protected override void HandleUnknownAction(string actionName)
{
    this.NotFound(actionName).ExecuteResult(this.ControllerContext);
}

因此对 {site}/ValidController/NotAnAction 的访问被正确路由。

但是访问 {site}/NotAController 不会。

我设置了一个包罗万象的路线:

routes.MapRoute(
    "MVC routes",
    "{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional });

routes.MapRoute(
    "Catch All", 
    "{*url}",
    new { controller = "System", action = "NotFound" });

catch all 正确捕获不匹配的路由。

因此 {site}/Invalid/Action/id/extra 通过 catch all 正确路由。

但是 {site}/Invalid 通过“MVC routes”路由被拾取并且 ASP.Net 去寻找 InvalidController,并且当它没有时抛出一个愚蠢的异常找到它。

我知道我可以在 web.config 级别覆盖它,但这只会重定向到页面。我想知道路由模式何时匹配但 Controller 不是有效的 Controller 名称。

我在哪里可以捕捉并改变这种行为?

最佳答案

我终于找到了这个问题的答案,虽然它仍然不理想。

您可以使用正则表达式限制允许匹配路由的 Controller 名称,因此如果我们假设 Controller 工厂的默认实现,我们可以找出所有可能支持的类名称:

// build up a list of known controllers, so that we don't let users hit ones that don't exist
var allMvcControllers = 
    from t in typeof(Global).Assembly.GetTypes()
    where t != null &&
        t.IsPublic &&
        !t.IsAbstract &&
        t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
        typeof(IController).IsAssignableFrom(t)
    select t.Name.Substring(0, t.Name.Length - 10);

// create a route constraint that requires the controller to be one of the reflected class names
var controllerConstraint = new
{
    controller = "(" + string.Join("|", allMvcControllers.ToArray()) + ")"
};

// default MVC route
routes.MapRoute(
    "MVC",
    "{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional },
    controllerConstraint);

// fall back route for unmatched patterns or invalid controller names
routes.MapRoute(
    "Catch All", 
    "{*url}",
    new { controller = "System", action = "NotFound" });

这并不理想,它在应用程序启动时增加了一个命中并且仍然感觉太复杂了,但它确实达到了预期的效果。

关于asp.net-mvc - 更正缺少 ASP.Net MVC Controller 的 404 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5701922/

相关文章:

c# - 我可以检查操作是否是 View 中的子操作吗?

asp.net-mvc - 我什么时候应该避免使用强类型 View 数据?

jquery - 使用 jquery 获取表单操作/url

ruby-on-rails - Rails:使用参数重定向

php - Kohana 3.2 路由和子域问题

regex - 为什么 MVC 验证对 "<"和 ">"不起作用?

.net - 用于访问 Gravatar 图像的 ASP.NET MVC 帮助程序

c# - NHibernate - 如何处理 NonUniqueObjectException?

AngularJs UI 路由器 - 具有多个 URL 的一种状态

jquery - 如何将整数数组从 asp.net mvc Controller 操作传递回 jquery 函数