在我的 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/