我喜欢首先对可能的错误进行分类。
对错误进行分类。
- 找不到页面(这是我的日志)。
- 通过尝试破解页面来破坏页面的参数
- 错误的用户数据输入错误。
- 完全未知的错误 - 我们必须修复的新错误。
- 一个非常严重的一般错误 - 没有运行 - 例如,数据库根本没有打开。
我们的目标
现在显示错误页面,但仅在极少数情况下。
因此,当用户在没有页面的情况下进行操作时,我们会尝试捕获用户的所有错误输入,并向他展示如何在没有任何错误的情况下继续操作。
全局错误处理程序
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以查看视图状态错误的示例以及如何处理它。
我知道 MVC 没有视图状态,但是您的代码中可能有其他加密字符串,或者您可以知道它何时被破坏的某种安全性。这是一般的想法:
if(IsPostBack && HashErrorOnParametres)
{
LogIt();
Responce.Redirect(Request.RawUrl, true);
return;
}
对于一个非常困难的一般错误
假设您的数据库根本没有打开,那么所有用户都开始从通用处理程序中看到错误页面。在那里,您可能有一个额外的选项来重新启动池,或者在过去 5 分钟内出现 20 个错误后停止页面,或者类似的事情,然后向您发送电子邮件以运行并修复这个非常困难的错误。
对于其余的软错误
我认为所有可能的已知错误必须在页面内使用 try/catch 进行处理,并向用户显示出错的消息,如果此错误来自用户,当然记录它以查看并修复它。
将页面分成几部分,也许一部分是抛出错误,其余部分工作正常,如果这不是那么重要,您可以简单地隐藏这部分,并显示其余部分,直到您修复它。例如,如果您只是显示有关产品的信息,而涉及某个部分的部分抛出错误,您可以简单地隐藏该部分并在日志中看到它并修复它。
有时我尝试使用每页处理错误,protected override void OnError(EventArgs e)
但这对我没有帮助,我将其删除。我处理每个操作的错误,如果它们不是关键的,我会隐藏它们,直到我修复它们。
其余的正常错误显示在用户身上,例如未输入正确的数据...一条消息并告诉他们要修复什么。
正如我所说,我的目标是根本不显示错误页面。