У меня проблема с пользовательскими ошибками в приложении 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));
}
Application_Error определенно запускается, потому что ведение журнала работает нормально, но вместо того, чтобы отображать мои пользовательские страницы ошибок, я получаю общие Go Go Daddy. Из заголовка блога, взятого выше, взят код, я заметил, что он использует Release Candidate 2 платформы MVC. Что-то изменилось в 1.0, из-за чего последняя строка кода не работает? Как обычно, прекрасно работает на моей машине .
Любые предложения будут с благодарностью.
Редактировать: забыл упомянуть, что я попробовал все 3 возможности для режима customErrors в Web.config (Off, On и RemoteOnly). Одинаковые результаты независимо от этого параметра.
Редактировать 2: И я также попробовал это с и без украшения [HandleError] на классах Controller.
Обновление: я разобрался и исправил 404. В Центре управления хостингом Go Daddy есть раздел панели «Настройки», в котором можно управлять поведением 404 и по умолчанию показывать их общую страницу, что, очевидно, переопределяет любые настройки Web.config. Таким образом, моя пользовательская страница 404 теперь отображается так, как задумано. Однако 500 и 503 все еще не работают. У меня есть код в HomeController для захвата статической текстовой версии контента, если Sql Server выдает исключение следующим образом:
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);
}
}
}
Вот код, который пытается извлечь статический контент:
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;
}
Я проверил, что если я изменяю строку подключения для генерации SqlException, код правильно регистрирует ошибку, а затем захватывает и отображает статическое содержимое. Но если я также изменю путь к статическому текстовому файлу в Web.config, чтобы протестировать 503-версию Home View, вместо этого я получу страницу, на которой нет ничего, кроме «служба недоступна». Вот и все. Нет пользовательского сообщения 503 с внешним видом сайта.
У кого-нибудь есть предложения по улучшению кода, которые могут помочь? Поможет ли это добавить разные заголовки в HttpResponse? Или Go Daddy безжалостно угоняет 503-е?