ASP.NET自定义错误页面 – Server.GetLastError()为空

我有一个自定义的错误页面为我的应用程序设置:

<customErrors mode="On" defaultRedirect="~/errors/GeneralError.aspx" /> 

在Global.asax,Application_Error(),下面的代码工作来获取exception详细信息:

  Exception ex = Server.GetLastError(); if (ex != null) { if (ex.GetBaseException() != null) ex = ex.GetBaseException(); } 

当我到达我的错误页面(〜/ errors / GeneralError.aspx.cs)时,Server.GetLastError()为null

有没有什么办法可以在错误页面上获取exception详细信息,而不是在Global.asax.cs中?

Vista / IIS7上的ASP.NET 3.5

仔细查看我的web.config设置, 这篇文章中的一条评论是非常有帮助的

在asp.net 3.5 SP1中有一个新的参数redirectMode

所以我们可以修改customErrors来添加这个参数:

 <customErrors mode="RemoteOnly" defaultRedirect="~/errors/GeneralError.aspx" redirectMode="ResponseRewrite" /> 

ResponseRewrite模式允许我们在不redirect浏览器的情况下加载“错误页面”,所以URL保持不变,对我来说重要的是,exception信息不会丢失。

好的,我发现这篇文章: http : //msdn.microsoft.com/en-us/library/aa479319.aspx

有这个非常说明性的图表:

图表http://i.msdn.microsoft.com/Aa479319.customerrors_01(en-us,MSDN.10).gif

实质上,为了获取这些exception细节,我需要自己将其存储在Global.asax中,以便以后在自定义错误页面上进行检索。

看起来最好的办法是做Global.asax的大部分工作,用自定义的错误页面来处理有用的内容而不是逻辑。

NailItDown和Victor说的一个组合。 首选/最简单的方法是使用Global.Asax来存储错误,然后redirect到您的自定义错误页面。

Global.asax

  void Application_Error(object sender, EventArgs e) { // Code that runs when an unhandled error occurs Exception ex = Server.GetLastError(); Application["TheException"] = ex; //store the error for later Server.ClearError(); //clear the error so we can continue onwards Response.Redirect("~/myErrorPage.aspx"); //direct user to error page } 

另外,你需要设置你的web.config

  <system.web> <customErrors mode="RemoteOnly" defaultRedirect="~/myErrorPage.aspx"> </customErrors> </system.web> 

最后,根据您存储在错误页面中的例外情况,执行任何您需要的操作:

 protected void Page_Load(object sender, EventArgs e) { // ... do stuff ... //we caught an exception in our Global.asax, do stuff with it. Exception caughtException = (Exception)Application["TheException"]; //... do stuff ... } 

尝试使用像Server.Transfer("~/ErrorPage.aspx"); 来自global.asax.cs的Application_Error()方法

然后从ErrorPage.aspx.cs的Page_Load() ,你应该可以做类似的事情: Exception exception = Server.GetLastError().GetBaseException();

Server.Transfer()似乎保持例外悬而未决。

虽然在这里有几个很好的答案,但我必须指出,在错误页面上显示系统exception消息是不好的做法(这正是我所假设的你想要做的)。 您可能会不经意地向恶意用户泄露您不希望这样做的内容。 例如,Sql Serverexception消息非常详细,可以在发生错误时给出数据库的用户名,密码和模式信息。 该信息不应该显示给最终用户。

我认为每个人都缺less的一个重要的考虑因素是负载平衡(web farm)scheme。 由于执行global.asax的服务器可能与执行自定义错误页面的服务器不同,因此在Application中隐藏exception对象是不可靠的。

我仍然在寻找一个可靠的解决scheme,这个问题在网上服务器场configuration,和/或从MS很好的解释,为什么你不能在自定义错误页面上的Server.GetLastError拿起例外,就像你可以在global.asax Application_Error中。

PS将数据存储在应用程序集合中,而不先locking并解锁,这是不安全的。

这是我的解决scheme..

在Global.aspx中:

 void Application_Error(object sender, EventArgs e) { // Code that runs when an unhandled error occurs //direct user to error page Server.Transfer("~/ErrorPages/Oops.aspx"); } 

在Oops.aspx中:

 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) LoadError(Server.GetLastError()); } protected void LoadError(Exception objError) { if (objError != null) { StringBuilder lasterror = new StringBuilder(); if (objError.Message != null) { lasterror.AppendLine("Message:"); lasterror.AppendLine(objError.Message); lasterror.AppendLine(); } if (objError.InnerException != null) { lasterror.AppendLine("InnerException:"); lasterror.AppendLine(objError.InnerException.ToString()); lasterror.AppendLine(); } if (objError.Source != null) { lasterror.AppendLine("Source:"); lasterror.AppendLine(objError.Source); lasterror.AppendLine(); } if (objError.StackTrace != null) { lasterror.AppendLine("StackTrace:"); lasterror.AppendLine(objError.StackTrace); lasterror.AppendLine(); } ViewState.Add("LastError", lasterror.ToString()); } } protected void btnReportError_Click(object sender, EventArgs e) { SendEmail(); } public void SendEmail() { try { MailMessage msg = new MailMessage("webteam", "webteam"); StringBuilder body = new StringBuilder(); body.AppendLine("An unexcepted error has occurred."); body.AppendLine(); body.AppendLine(ViewState["LastError"].ToString()); msg.Subject = "Error"; msg.Body = body.ToString(); msg.IsBodyHtml = false; SmtpClient smtp = new SmtpClient("exchangeserver"); smtp.Send(msg); } catch (Exception ex) { lblException.Text = ex.Message; } } 

我想你在这里有几个select。

您可以将最后一个exception存储在会话中,并从您的自定义错误页面中检索它; 或者你可以redirect到Application_error事件中的自定义错误页面。 如果您select后者,则要确保使用Server.Transfer方法。

这与下面这两个主题有关,我想同时获取GetHtmlErrorMessage和Session on Error页面。

ResponseRewrite后会话为空

为什么当redirectMode = ResponseRewrite时HttpContext.Session为空

我试过,看到没有需要的解决schemeServer.Transfer() or Response.Redirect()

首先:在web.config中删除ResponseRewrite

Web.config文件

 <customErrors defaultRedirect="errorHandler.aspx" mode="On" /> 

然后Global.asax

  void Application_Error(object sender, EventArgs e) { if(Context.IsCustomErrorEnabled) { Exception ex = Server.GetLastError(); Application["TheException"] = ex; //store the error for later } } 

然后errorHandler.aspx.cs

  protected void Page_Load(object sender, EventArgs e) { string htmlErrorMessage = string.Empty ; Exception ex = (Exception)Application["TheException"]; string yourSessionValue = HttpContext.Current.Session["YourSessionId"].ToString(); //continue with ex to get htmlErrorMessage if(ex.GetHtmlErrorMessage() != null){ htmlErrorMessage = ex.GetHtmlErrorMessage(); } // continue your code } 

为参考

http://www.developer.com/net/asp/article.php/3299641/ServerTransfer-Vs-ResponseRedirect.htm

它为我工作。 在MVC 5中

~\Global.asax

 void Application_Error(object sender, EventArgs e) { FTools.LogException(); Response.Redirect("/Error"); } 

~\Controllers创buildErrorController.cs

 using System.Web.Mvc; namespace MVC_WebApp.Controllers { public class ErrorController : Controller { // GET: Error public ActionResult Index() { return View("Error"); } } } 

~\Models创buildFunctionTools.cs

 using System; using System.Web; namespace MVC_WebApp.Models { public static class FTools { private static string _error; private static bool _isError; public static string GetLastError { get { string cashe = _error; HttpContext.Current.Server.ClearError(); _error = null; _isError = false; return cashe; } } public static bool ThereIsError => _isError; public static void LogException() { Exception exc = HttpContext.Current.Server.GetLastError(); if (exc == null) return; string errLog = ""; errLog += "**********" + DateTime.Now + "**********\n"; if (exc.InnerException != null) { errLog += "Inner Exception Type: "; errLog += exc.InnerException.GetType() + "\n"; errLog += "Inner Exception: "; errLog += exc.InnerException.Message + "\n"; errLog += "Inner Source: "; errLog += exc.InnerException.Source + "\n"; if (exc.InnerException.StackTrace != null) { errLog += "\nInner Stack Trace: " + "\n"; errLog += exc.InnerException.StackTrace + "\n"; } } errLog += "Exception Type: "; errLog += exc.GetType().ToString() + "\n"; errLog += "Exception: " + exc.Message + "\n"; errLog += "\nStack Trace: " + "\n"; if (exc.StackTrace != null) { errLog += exc.StackTrace + "\n"; } _error = errLog; _isError = true; } } } 

~\Views创build文件夹Error并在~\Views\Error创buildError.cshtml

 @using MVC_WebApp.Models @{ ViewBag.Title = "خطا"; if (FTools.ThereIsError == false) { if (Server.GetLastError() != null) { FTools.LogException(); } } if (FTools.ThereIsError == false) { <br /> <h1>No Problem!</h1> } else { string log = FTools.GetLastError; <div>@Html.Raw(log.Replace("\n", "<br />"))</div> } } 

如果你input这个地址localhost/Error 打开页面没有错误


如果发生错误 发生错误

可以代替显示错误,将variables“log”存储在数据库中

资料来源: 微软ASP.Net