Kei*_*ith 3 asp.net-mvc routing asp.net-mvc-routing asp.net-mvc-2
我有一个MVC 2应用程序,应该总是提供一个"漂亮的"404页面.
但是目前我得到了一个低级别的.Net:"'/ sitename'应用程序中的服务器错误..."
我有一个基本控制器,它有一个NotFound动作,将呈现漂亮的404页面.
处理缺失的操作:
protected override void HandleUnknownAction(string actionName)
{
this.NotFound(actionName).ExecuteResult(this.ControllerContext);
}
Run Code Online (Sandbox Code Playgroud)
所以访问{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" });
Run Code Online (Sandbox Code Playgroud)
catch全部正确捕获不匹配的路由.
所以{site}/Invalid/Action/id/extra通过catch all正确路由.
然而{site}/Invalid,通过"MVC路由"路由获取并且ASP.Net寻找InvalidController,并且当它找不到时抛出一个愚蠢的异常.
我知道我可以在web.config关卡中覆盖它,但这只是重定向到页面.我想知道路由模式何时匹配但控制器不是有效的控制器名称.
我在哪里可以捕捉并改变这种行为?
我终于找到了答案,虽然它仍然不理想.
您可以使用正则表达式限制允许匹配路由的控制器名称,因此,如果我们假设控制器工厂的默认实现,我们可以找出所支持的所有可能的类名:
// 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" });
Run Code Online (Sandbox Code Playgroud)
这不是理想的,它增加了应用程序开始的打击,但仍然感觉太复杂,但它确实具有所需的效果.
| 归档时间: |
|
| 查看次数: |
4060 次 |
| 最近记录: |