Bry*_*yan 14 error-handling asp.net-mvc shared-hosting global-asax
我在我的共享主机上部署的ASP.NET MVC应用程序上遇到自定义错误问题.我创建了一个ErrorController并将以下代码添加到Global.asax以捕获未处理的异常,记录它们,然后将控制转移到ErrorController以显示自定义错误.此代码取自此处:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Response.Clear();
HttpException httpEx = ex as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpEx == null)
{
routeData.Values.Add("action", "Index");
}
else
{
switch (httpEx.GetHttpCode())
{
case 404:
routeData.Values.Add("action", "HttpError404");
break;
case 500:
routeData.Values.Add("action", "HttpError500");
break;
case 503:
routeData.Values.Add("action", "HttpError503");
break;
default:
routeData.Values.Add("action", "Index");
break;
}
}
ExceptionLogger.LogException(ex); // <- This is working. Errors get logged
routeData.Values.Add("error", ex);
Server.ClearError();
IController controller = new ErrorController();
// The next line doesn't seem to be working
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
Run Code Online (Sandbox Code Playgroud)
Application_Error肯定会触发,因为日志记录工作正常,但我没有显示自定义错误页面,而是获得Go Daddy泛型.从博客文章的标题中取出上面的代码,我注意到它使用了MVC框架的Release Candidate 2.在1.0中有什么变化使最后一行代码不起作用?像往常一样,它在我的机器上运行良好.
任何建议将不胜感激.
编辑:忘了提到我已经尝试了Web.config(Off,On和RemoteOnly)中的customErrors模式的所有3种可能性.无论此设置如何,结果都相同.
编辑2:我也尝试过在Controller类上有[HandleError]装饰的情况.
更新:我已经找到并修复了404.Go Daddy的托管控制中心的"设置"面板中有一部分可以控制404行为,默认情况下是显示其通用页面,显然这会覆盖任何Web.config设置.所以我的自定义404页面现在按预期显示.但是,500和503仍然无法正常工作.如果Sql Server抛出异常,我在HomeController中有代码来获取内容的静态文本版本,如下所示:
public ActionResult Index()
{
CcmDataClassesDataContext dc = new CcmDataClassesDataContext();
// This might generate an exception which will be handled in the OnException override
HomeContent hc = dc.HomeContents.GetCurrentContent();
ViewData["bodyId"] = "home";
return View(hc);
}
protected override void OnException(ExceptionContext filterContext)
{
// Only concerned here with SqlExceptions so an HTTP 503 message can
// be displayed in the Home View. All others will bubble up to the
// Global.asax.cs and be handled/logged there.
System.Data.SqlClient.SqlException sqlEx =
filterContext.Exception as System.Data.SqlClient.SqlException;
if (sqlEx != null)
{
try
{
ExceptionLogger.LogException(sqlEx);
}
catch
{
// couldn't log exception, continue without crashing
}
ViewData["bodyId"] = "home";
filterContext.ExceptionHandled = true;
HomeContent hc = ContentHelper.GetStaticContent();
if (hc == null)
{
// Couldn't get static content. Display friendly message on Home View.
Response.StatusCode = 503;
this.View("ContentError").ExecuteResult(this.ControllerContext);
}
else
{
// Pass the static content to the regular Home View
this.View("Index", hc).ExecuteResult(this.ControllerContext);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是尝试获取静态内容的代码:
public static HomeContent GetStaticContent()
{
HomeContent hc;
try
{
string path = Configuration.CcmConfigSection.Config.Content.PathToStaticContent;
string fileText = File.ReadAllText(path);
string regex = @"^[^#]([^\r\n]*)";
MatchCollection matches = Regex.Matches(fileText, regex, RegexOptions.Multiline);
hc = new HomeContent
{
ID = Convert.ToInt32(matches[0].Value),
Title = matches[1].Value,
DateAdded = DateTime.Parse(matches[2].Value),
Body = matches[3].Value,
IsCurrent = true
};
}
catch (Exception ex)
{
try
{
ExceptionLogger.LogException(ex);
}
catch
{
// couldn't log exception, continue without crashing
}
hc = null;
}
return hc;
}
Run Code Online (Sandbox Code Playgroud)
我已经验证,如果我更改连接字符串以生成SqlException,则代码会正确记录错误,然后抓取并显示静态内容.但是,如果我还在Web.config中更改静态文本文件的路径来测试主视图的503版本,那么我得到的是一个除"服务不可用"之外的页面.而已.没有自定义503消息与网站的外观和感觉.
有没有人对代码的改进有任何建议可能会有所帮助?将不同的标题添加到HttpResponse会有帮助吗?还是Go Daddy狠狠地劫持了503s?
Bry*_*yan 29
我找到了解决方案,而且非常简单.事实证明问题实际上是在IIS7中.在Visual Studio中调试此问题时,我看到了之前没有注意到的HttpResponse对象的属性:
public bool TrySkipIisCustomErrors { get; set; }
Run Code Online (Sandbox Code Playgroud)
这引导我到我最近的搜索引擎,由Rick Strahl发布了一篇很棒的博客文章,另一篇关于angrypets.com的博客文章以及这里的问题.这些链接比我更好地解释了血腥细节,但Rick的帖子引用了它很好的说法:
这里真正的混乱是因为错误被ASP.NET捕获,但最终仍由IIS处理,它查看500状态代码并返回库存IIS错误页面.
在集成模式下,此行为似乎也特定于IIS7.来自msdn:
在IIS 7.0中以经典模式运行时,TrySkipIisCustomErrors属性的默认值为true.在集成模式下运行时,TrySkipIisCustomErrors属性的默认值为false.
所以我最终要做的就是Response.TrySkipIisCustomErrors = true;
在任何设置Response.StatusCode
为500或503的代码之后添加,现在一切都按设计运行.
归档时间: |
|
查看次数: |
7750 次 |
最近记录: |