asp.net - 如何在我的 ASP.NET 应用程序中创建一个 "generic error"页面,以便它处理在提供该页面本身时触发的错误?

标签 asp.net .net iis error-handling

在我的 ASP.NET MVC 应用程序中,我希望有一个通用错误页面与返回的 HTTP 500 一起显示。类似 this page on Stack Overflow 的内容。 .

当然,我希望重用尽可能多的代码,以便页面的样式与应用程序中的其他页面相同,因此我希望有一个重用母版页的 ASP.NET 页面,而不是纯 HTML 文件。但是,如果我这样做,我有一个页面,其中包含一些服务器端可执行代码,用于创建提供给客户端的实际 HTML。在 Stack Overflow 通用错误页面的情况下,它是检查用户是否已注册、检索其代表等并将其元素插入 HTML 的代码。

该代码可能会失败,如果发生这种情况,页面将无法正确构建,并且会在服务器中引发异常。

我如何优雅地处理这种情况(为错误页面构建 HTML 时出错)?典型的方法是什么?

最佳答案

我喜欢首先对可能的错误进行分类。

对错误进行分类。

  • 找不到页面(这是我的日志)。
  • 通过尝试破解页面来破坏页面参数
  • 错误的用户数据输入导致的错误。
  • 完全未知的错误 - 我们必须修复的新错误。
  • 一个非常困难的一般错误 - 没有运行 - 例如,数据库根本没有打开。

  • 我们的目标

    现在显示错误页面,但仅在极少数情况下。

    因此,当用户在没有页面的情况下进行操作时,我们会 try catch 用户的所有错误输入,并向他展示如何继续操作而不会出现任何错误。

    全局错误处理程序

    您可以从 global.asax 上的捕获开始使用 void Application_Error(object sender, EventArgs e) 的所有错误
    void Application_Error(object sender, EventArgs e) 
    {
        try
        {
            Exception LastOneError = Server.GetLastError();
    
            if (LastOneError != null)
            {
                Debug.Fail("Unhandled error: " + LastOneError.ToString());
    
                if (!(EventLog.SourceExists(SourceName)))
                    EventLog.CreateEventSource(SourceName, LogName);
    
                EventLog MyLog = new EventLog();
                MyLog.Source = SourceName;
                StringBuilder cReportMe = new StringBuilder();
    
                cReportMe.Append("[Error come from ip:");
                cReportMe.Append(GetRemoteHostIP());
                cReportMe.Append("] ");
                cReportMe.Append("Last Error:");
                cReportMe.Append(LastOneError.ToString());
    
                if (LastOneError.ToString().Contains("does not exist."))
                {
                    // page not found
                    MyLog.WriteEntry(cReportMe.ToString(), EventLogEntryType.Warning, 998);
                }
                else
                {
                    MyLog.WriteEntry(cReportMe.ToString(), EventLogEntryType.Error, 999);
                }               
            }
        }
        catch (Exception ex)
        {
            Debug.Fail("Unhandled error: " + GlobalFun.GetErrorMessage(ex));
        }
    
        string cTheFile = HttpContext.Current.Request.Path;
    
        // to avoid close loop and stackoverflow
        if(!cTheFile.EndsWith("error.aspx"))
            Server.Transfer("~/error.aspx");
    }
    

    这个全局错误句柄有一个主要目标,在到达这里之前告诉我什么不起作用并且无法处理它,所以我记录它(而不是记录它的方式)并尽快修复它。当我调试我的代码时,我没有让服务器传输能够快速定位错误。

    对于黑客错误案例

    在这种情况下,最好现在显示任何错误,而只需通过重定向来重新加载页面。如何知道它是否试图破解页面?

    如果在回发时您会收到一些您知道的参数的 CRC/hach 错误。看那个答案https://stackoverflow.com/a/2551810/159270查看 View 状态错误的示例以及如何处理它。

    我知道 MVC 没有 View 状态,但是您的代码中可能有其他加密字符串,或者您可以在其损坏时知道的某种安全性。这是一般的想法:
    if(IsPostBack && HashErrorOnParametres)
    {
      LogIt();
      Responce.Redirect(Request.RawUrl, true);
      return;
    }
    

    对于非常困难的一般错误

    假设您的数据库根本没有打开,那么所有用户都开始从通用处理程序看到错误页面。在那里,您可能有一个额外的选项来重新启动池,或者在过去 5 分钟内出现 20 个错误后停止页面,或者类似的事情,然后向您发送电子邮件以运行并修复这个非常严重的错误。

    对于其余的软错误

    我认为所有可能的已知错误都必须在页面内使用 try/catch 处理并向用户显示错误的消息,如果此错误来自用户,当然记录它以查看并修复它。

    将页面分成几部分,也许一部分是抛出错误,其余部分工作正常,如果这不是那么重要,您可以简单地隐藏这一部分,并显示其余部分,直到您修复它。例如,如果您只显示有关产品的信息,而谈论某个部分的部分引发错误,您可以简单地隐藏该部分并在日志中查看并修复它。

    有一段时间我尝试使用 protected override void OnError(EventArgs e) 处理每页的错误但这对我没有帮助,我将其删除。我处理每个 Action 的错误,如果它们不重要,我会隐藏它们,直到我修复它们。

    其余的正常错误会显示在用户身上,例如没有输入正确的数据......一条消息并告诉他们要修复什么。

    正如我所说,我的目标是根本不显示错误页面。

    关于asp.net - 如何在我的 ASP.NET 应用程序中创建一个 "generic error"页面,以便它处理在提供该页面本身时触发的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10751363/

    相关文章:

    javascript - 如何在 asp.net 中调试 javascript?

    asp.net - 如何动态设置 ValidationGroup

    .net - 在 vector 的非托管 vector 中访问二维数组 (C++)

    c# - 没有强命名的代码签名是否会使您的应用程序容易被滥用?

    reactjs - IIS 8.5 重写规则子目录和 ReactJs

    asp.net - 如何在 asp.net BundleConfig 中忽略特定包以进行优化

    jquery - 如何使用jquery在gridview中获取选定的(单选按钮)行值(标签)

    c# - Autofac:如何使用动态值注入(inject)属性?

    c# - 本地主机上的 IIS 中的动态内容始终出现 404 错误

    powershell - 列出重定向目标 (URL) IIS 站点