sha*_*oth 4 .net asp.net iis error-handling
在我的ASP.NET MVC应用程序中,我希望有一个通用的错误页面,它与返回的HTTP 500一起显示.类似于Stack Overflow上的这个页面.
当然我想重用尽可能多的代码,以便页面的样式与我的应用程序中的其他页面的样式相同,所以我希望有一个ASP.NET页面重用母版页,而不是纯HTML文件.但是,如果我这样做,我有一个页面,其中包含一些服务器端可执行代码,用于创建提供给客户端的实际HTML.在Stack Overflow一般错误页面的情况下,代码检查用户是否已注册,检索他的代表等,并将其中的元素插入HTML.
该代码可能会失败,如果发生这种情况,页面就没有正确构造,并且服务器中会抛出异常.
如何正常处理这种情况(为错误页面构建HTML时出错)?什么是典型的方法?
我想首先对可能的错误进行分类.
现在显示错误页面,但仅限于极少数情况.
因此,当用户使用页面进行操作时,我们会尝试捕获用户的所有错误输入,并告诉他如何继续执行任何错误.
您可以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");
}
Run Code Online (Sandbox Code Playgroud)
这个全局错误句柄有一个主要目标,告诉我什么没有工作,并且在到达此处之前无法处理它,所以我记录它(不是记录它的方式)并很快修复它.当我调试我的代码时,我没有使服务器传输能够快速找到错误.
在这种情况下,最好现在显示任何错误,但只需通过重定向重新加载页面.如何知道它是否试图入侵该页面?
如果在回发后你得到你知道的参数的CRC/hach错误.看看答案/sf/answers/178626731/查看视图状态错误的示例以及如何处理它.
我知道MVC没有viewstate,但是你的代码上可能有其他加密字符串,或者某种安全性,你知道它什么时候坏了.这是一般的想法:
if(IsPostBack && HashErrorOnParametres)
{
LogIt();
Responce.Redirect(Request.RawUrl, true);
return;
}
Run Code Online (Sandbox Code Playgroud)
假设您的数据库根本没有打开,然后所有用户都开始从常规处理程序中看到错误页面.在那里你可能有一个额外的选项来重新启动池,或者在最后5分钟或类似的情况下20个错误后停止页面,并发送电子邮件来运行并修复这个非常困难的错误.
我认为必须使用try/catch在页面内处理所有可能的已知错误,并向用户显示出现错误的消息,如果此错误来自用户,并且当然记录它以查看并修复它.
打破部分页面,也许一部分是抛出错误,其余部分工作正常,如果这不是那么重要,你可以简单地隐藏这部分,并显示其余部分,直到你修复它.例如,如果您只显示有关产品的信息,并且说出一个部件的部分会抛出错误,您可以简单地隐藏此部件并在日志中查看并修复它.
有一段时间我试图处理每页错误,protected override void OnError(EventArgs e)但这对我没有帮助,我将其删除.我处理每个操作的错误,如果它们不重要,我会隐藏它们直到我修复它们.
其余的正常错误显示在用户身上,例如没有输入正确的数据......一条消息,告诉他们要修复的内容.
正如我所说,我的目标是根本不显示错误页面.
基本上在你的 web.config 中你需要这样的东西:
<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPages/Oops.aspx">
</customErrors>
Run Code Online (Sandbox Code Playgroud)
当然,错误页面的路径会与上面的不同。
您可以更一般地了解如何处理特定错误,例如这样的 404:
<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPages/Oops.aspx">
<error statusCode="404" redirect="~/ErrorPages/404.aspx" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
编辑:
根据评论,我得到的信息如下:
当您构建“oops.aspx”页面时,我建议您保持简单;如果可能的话,根本没有执行代码。如果您确实需要执行“oops.aspx”中的代码,则将该代码放入一个try..catch块中并消除异常:
try {
// Your oops code.
}
catch (Exception e) {
// Do nothing with the exception.
// Maybe plonk it in a log file, or System.Diagnostics.Trace.WriteLine(e.Message);
}
Run Code Online (Sandbox Code Playgroud)
关键是您要避免调用“oops.aspx”,因为“oops.aspx”本身会导致异常!递归问题啊嘿。
您不需要在母版页中尝试...catch(除非您愿意),我的观点只是集中在“oops.aspx”页面上。
| 归档时间: |
|
| 查看次数: |
8384 次 |
| 最近记录: |