当前位置: 首页 > 知识库问答 >
问题:

ASP。NET MVC自定义错误

贝钧
2023-03-14

我的目标是在应用程序中创建一个错误处理机制,处理所有可管理的错误,而不仅仅是与MVC相关的错误。所以我没有使用HandleErrorAttribute模式,因为它只针对MVC错误,而不是其他托管错误。

在我的全球。asax我有:

protected void Application_Error()
{
    string displayError = ConfigurationManager.AppSettings["DisplayError"];
    NameValueCollection serverVariables;
    int loop1, loop2;
    StringBuilder serverVariableKeys = new StringBuilder();
    Exception exception = Server.GetLastError();
    HttpException httpException = exception as HttpException;

    if (HttpContext.Current != null)
    {
            // loop through and get server vars
    }

    if (exception != null)
        // Log Error

    // Redirect to Error page if set to basic mode
    if (!string.IsNullOrWhiteSpace(displayError) && displayError.ToLower() == "basic")
    {
        Response.Clear();
    Server.ClearError(); // needed for redirect to work

    var routeData = new RouteData();
    routeData.Values["controller"] = "Error";
    routeData.Values["action"] = "General";
    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;
        }
    }

    IController errorsController = new Controllers.ErrorController();
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    errorsController.Execute(rc);
    }
}

我有一个< code>ErrorController,它具有< code >常规、< code>Http403和< code>Http404操作。我有与每个动作相对应的视图。

在我的网络配置中,我有:

  <system.web>  
    <!-- removed bits to reduce space -->
    <customErrors mode="On" />
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules >
      <remove name="UrlRoutingModule-4.0" />
      <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
      <remove name="Session"/>
      <add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition=""/>
    </modules>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <httpErrors errorMode="Detailed" />
  </system.webServer>

这适用于许多与托管代码相关的情况,但是当IIS接管时,例如错误的静态文件调用(example.com/BadFileName.gif ),它将从IIS返回一个错误,该错误会泄露服务器的详细信息,例如本地文件路径。这是因为web.config中的以下行:

<httpErrors errorMode="Detailed" />

但是,当我将 errorMode 设置为其他值(如“自定义”)或仅删除该行时,我的自定义错误处理将停止运行,并且将返回包括托管代码错误在内的所有内容的默认 IIS 错误消息。

我已经尝试了很多事情,以获得自定义错误的工作没有这个设置没有任何运气,包括:

    < li >将< code>CustomError设置为< code>mode="Off" < li >在< code>customError下定义错误节点以重定向到我的控制器 < li >在< code>httpErrors下定义错误节点以重定向到我的控制器

当我逐步调试时,我可以看到对控制器的调用,但最终IIS会发送响应。错误日志记录确实Application_Error被正确调用,因此代码确实让应用程序在某一点上处理它。

申请详情:

  • ASP。NET MVC 4.0
  • 托管在IIS 7.5上(Azure网站预览)

有没有办法不使用


共有2个答案

陆博易
2023-03-14

如果你想在你的应用中处理这个问题,你可以写一个自定义的处理程序或者使用HandleError属性,这里是一个很好的例子,说明了一种处理这个问题的方法,而不是必须使用IIS作为支撑。因为不是所有的IIS主机提供商都允许在服务器级别进行这种类型的定制,所以IMO不是一种好方法,因为它会在部署时创建额外的配置。

夏侯衡
2023-03-14
匿名用户

您看到该行为的原因可能是您的Application_Error处理程序被正确调用(并调用您的控制器),但随后 IIS 正在拦截 500 错误并显示其自己的错误页面。(尽管您的Application_Error处理程序本身也可能抛出异常,但这是您需要排除的)

因为您想处理所有错误(例如您提到的静态文件错误),所以您可能无法依赖ASP.NET或ASP.NETMVC为您进行初始错误检测。并非所有错误都来自您的应用程序!

最好的办法是尽可能多地依靠IIS 7.5的错误处理,而不是过早地让自己参与进来。让IIS为您做最初的错误检测,这要容易得多。

尝试将以下内容放入< code>web.config中,替换现有的< code>httpErrors节点:-

<httpErrors errorMode="Custom" existingResponse="Replace">
  <clear />
  <error statusCode="400" responseMode="ExecuteURL" path="/Error" />
  <error statusCode="403" responseMode="ExecuteURL" path="/Error/Forbidden" />
  <error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
  <error statusCode="500" responseMode="ExecuteURL" path="/Error" />
</httpErrors>

完全删除定义错误节点。这是不必要的。

记住并确保错误控制器设置了正确的状态代码:-

public ActionResult Forbidden()
{
    Response.StatusCode = 403;
    return this.View();
}

然后,除了注销您的< code>Application_Error处理程序之外,您应该能够放弃所有事情——尽管我认为您最好创建自己的< code > http module ;在< code>web.config中的modules节点上设置< code > runAllManagedModulesForAllRequests ,有助于您捕捉可能会漏掉的错误。

我已经在Azure网站预览版上运行了这个设置(尽管我个人使用elmah进行日志记录),它可以捕获所有内容,除了明显来自未能解析web.config的任何错误。

我在github上放了一个完整的使用httpErrors定制错误页面的例子。你也可以在azure网站上看到它的现场直播。

 类似资料:
  • 我们正在开发具有移动部分和网络用户界面的应用程序。Web UI使用角,我们在后端配置cors时遇到了问题。我们的代码如下(只是对我们的问题很重要的代码): 从stackoverflow上的文档和其他帖子来看,这应该是可行的,但不是。我们错过了什么? thnx 编辑: 这是邮递员的请求: 卷曲'https://guw.azurewebsites.net/api/token'-X OPTIONS-H'

  • 我一直在搜索这个主题,但没有找到我想要的。基本上,我开始用UML的所有东西,用例,类图来计划一个项目。然后我们决定使用ASP。NET MVC。该应用程序是一种O-Desk或Elance 我有用户,承包商,公司,主持人和管理员。 我有点困惑模型应该如何表示这个用户,以及如何使用asp设置权限和角色。net mvc特性。 在一个正常的应用程序中,我会为他们每个人都创建一个类,他们可能会扩展User,其

  • 虽然Visual Studio和Visual Studio Code MVC模板附带了一些客户端包,如jQuery、jQueryValide、bootstrap等。bower.json和. Bowerrc文件完全丢失,所以当我进入VS bowers包管理器时,我看不到已经安装的包这是相当烦人。 问题是这在两周前开始发生在我身上(大约在我尝试npm package manager并进行VS代码更新时

  • Apache可以让网站管理员自己自定义对一些错误和问题的响应。 自定义的响应可以定义为当服务器检测到错误或问题时才被激活。 如果一个脚本崩溃并产生"500 Server Error"响应,那么这个响应可以被更友好的提示替换或者干脆用重定向语句跳到其他的URL(本地的或外部的)。 行为 老式的行为 Apache1.3 会响应一些对于用户没有任何意义的错误或问题信息,而且不会将产生这些错误的原因写入日

  • 所有的错误最终都会被 Tango.ErrHandler 进行处理。 你可以自定义你的错误处理方式来替代默认的。例如: var ( prefix = "<html><head>tango</head><body><div>" suffix = fmt.Sprintf("</div><div>version: %s</div></body></html>", tango.Version

  • Flask 自带了很顺手的 abort() 函数用于以一个 HTTP 失败代码 中断一个请求,他也会提供一个非常简单的错误页面,用于提供一些基础的描述。 这个页面太朴素了以至于缺乏一点灵气。 依赖于错误代码的不同,用户看到某个错误的可能性大小也不同。 通常的错误代码 下面列出了一些用户经常遇到的错误代码,即使在这个应用准确无误的情况下也可能发生: 404 Not Found 经典的“哎呦,您输入的