使用Server.TransferRequest()传递视图模型

Jon*_*ood 6 .net c# asp.net error-handling asp.net-mvc

我正在尝试微调我的MVC应用程序中的错误处理.

我在web.config中启用了自定义错误,并添加了以下代码Application_Error.

Global.asax中

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError() as Exception;
    if (exception != null)
    {
        Context.ClearError();
        Context.Response.TrySkipIisCustomErrors = true;

        string path = (exception is HttpException && (exception as HttpException).GetHttpCode() == 404) ?
            "~/Error/NotFound" :
            "~/Error/Index";
        Context.Server.TransferRequest(path, false);
    }
}
Run Code Online (Sandbox Code Playgroud)

ErrorController.cs

[AllowAnonymous]
public ActionResult Index()
{
    Response.Clear();
    Response.StatusCode = 503;
    Response.TrySkipIisCustomErrors = true;
    return View();
}

[AllowAnonymous]
public ActionResult NotFound()
{
    Response.Clear();
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true;
    return View();
}
Run Code Online (Sandbox Code Playgroud)

Web.config文件

<system.web>
  <customErrors mode="RemoteOnly" defaultRedirect="~/Error">
    <error statusCode="404" redirect="~/Error/NotFound"/>
    <error statusCode="500" redirect="~/Error" />
  </customErrors>
</system.web>
Run Code Online (Sandbox Code Playgroud)

这似乎运作得相当好.但是,如何将一些错误详细信息传递给我的错误控制器?

此外,还有一些关于获取异常详细信息到我的错误控制器的提示,以了解控制器中发生的异常.

注意:我不想在这里使用重定向.这样做会告诉Google这样的抓取工具有关该网址的错误信息.

小智 6

如果要在错误控制器中获取错误详细信息,而不是在Application_Error函数中清除错误详细信息(Context.ClearError()).

一旦进入ErrorController Action再次获取最后一个错误然后清除它.

HttpContext.Server.GetLastError()
Run Code Online (Sandbox Code Playgroud)

如果要获取发生异常的控制器和操作名称,可以使用下面的代码来获取详细信息

Request.RequestContext.RouteData.Values["controller"]
Request.RequestContext.RouteData.Values["action"]
Run Code Online (Sandbox Code Playgroud)

此外,如果您想从Application_Error函数运行ErrorController和Specific Action,您可以执行以下操作

   protected void Application_Error()
   {

Exception exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Errors";
routeData.Values["action"] = "Common";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
  Response.StatusCode = httpException.GetHttpCode();
  switch (Response.StatusCode)
{
  case 403:
    routeData.Values["action"] = "Http403";
    break;
  case 404:
    routeData.Values["action"] = "Http404";
    break;
  case 400:
    routeData.Values["action"] = "Http400";
    break;
  }
}

Response.TrySkipIisCustomErrors = true;
IController errorsController = new ErrorsController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);

/* This will run specific action without redirecting */
errorsController.Execute(rc);

}
Run Code Online (Sandbox Code Playgroud)

如果要将错误作为对象传递给错误控制器,则可以添加如下所示的额外路由数据

routeData.Values["errorDetail"] = httpException;
Run Code Online (Sandbox Code Playgroud)