public class MvcApplication : HttpApplication
{
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 404)
{
Response.Clear();
var rd = new RouteData();
rd.DataTokens["area"] = "AreaName"; // In case controller is in another area
rd.Values["controller"] = "Errors";
rd.Values["action"] = "NotFound";
IController c = new ErrorsController();
c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
}
}
}
错误控制器:
public sealed class ErrorsController : Controller
{
public ActionResult NotFound()
{
ActionResult result;
object model = Request.Url.PathAndQuery;
if (!Request.IsAjaxRequest())
result = View(model);
else
result = PartialView("_NotFound", model);
return result;
}
}
编辑:
如果你使用 IoC (例如 AutoFac) ,你应该使用以下方法创建你的控制器:
var rc = new RequestContext(new HttpContextWrapper(Context), rd);
var c = ControllerBuilder.Current.GetControllerFactory().CreateController(rc, "Errors");
c.Execute(rc);
而不是
IController c = new ErrorsController();
c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
马可的回应是最好的解决方案。我需要控制我的错误处理,我的意思是真正的 CONTROL 它。当然,我对解决方案进行了一些扩展,并创建了一个完整的错误管理系统来管理所有事情。我也在其他博客中读到过这个解决方案,它似乎被大多数高级开发人员所接受。
下面是我使用的最终代码:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 404)
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "ErrorManager";
routeData.Values["action"] = "Fire404Error";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 404:
routeData.Values["action"] = "Fire404Error";
break;
}
}
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
IController errormanagerController = new ErrorManagerController();
HttpContextWrapper wrapper = new HttpContextWrapper(Context);
var rc = new RequestContext(wrapper, routeData);
errormanagerController.Execute(rc);
}
}
在我的 ErrorManager 控制器中:
public void Fire404Error(HttpException exception)
{
//you can place any other error handling code here
throw new PageNotFoundException("page or resource");
}
现在,在我的操作中,我抛出了一个我已经创建的自定义异常。而且我的 Controller 继承自我创建的自定义 Controller Based 类。创建自定义基础控制器是为了重写错误处理。下面是我自定义的 Base Controller 类: