我有一个asp.net mvc 3应用程序,IIS7和IIS express在本地,它使用Application_Error记录异常并重定向到自定义错误页面。我的应用程序有不同的区域,只要控制器或操作不匹配,就会调用application_error,但不适用于该区域。
以下是使用路线的示例:
routes.MapRoute(
"Default",
"{region}/{controller}/{action}/{id}",
new { region = "uk", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { region = new RegionWhitelistConstraint() } // constraint for valid regions
);
在这种情况下,将为/ uk / NotFoundPage触发Application_Error,但不会针对/ foo / Home
触发这里是区域的约束:
public class RegionWhitelistConstraint : IRouteConstraint
{
public bool Match(System.Web.HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var whiteList = Region.DefaultWhiteList;
var currentRegionValue = values[parameterName].ToString();
return whiteList.Contains(currentRegionValue);
}
}
我已经看到了this的问题,建议添加一个catch所有路由,但除此之外我想知道是否有一种方法可以触发Application_Error,因为它是为控制器或操作完成的。
答案 0 :(得分:2)
您可以在约束类中抛出异常。这将由Application_Error处理:
public class RegionWhitelistConstraint : IRouteConstraint
{
public bool Match(System.Web.HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var whiteList = Region.DefaultWhiteList;
var currentRegionValue = values[parameterName].ToString();
var match = whiteList.Contains(currentRegionValue);
if (!match)
{
throw new HttpException(404, "Not Found");
}
return match;
}
}
答案 1 :(得分:0)
我弄清楚问题是什么:当一个控制器或一个动作出错时,它们仍然与路线系统匹配:
routes.MapRoute(
"Default",
"{region}/{controller}/{action}/{id}",
new { region = "uk", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { region = new RegionWhitelistConstraint() } // constraint for valid regions
);
但是当该区域不在白名单中时,它不匹配。这使得绕过application_error。我使用的解决方案是创建一条捕获路线:
routes.MapRoute(
"NotFound",
"{*url}",
new { region = "uk", controller = "Error", action = "NotFound", id = UrlParameter.Optional }
);
以及引发HttpException的操作:
[HttpGet]
public ActionResult NotFound()
{
throw new HttpException(404, "Page not found");
}