Niestandardowe strony błędów aplikacji ASP.NET MVC nie są wyświetlane w udostępnionym środowisku hostingu
Mam problem z niestandardowymi błędami w aplikacji ASP.NET MVC wdrożonej na moim udostępnionym hoście. Stworzyłem kontroler ErrorController i dodałem następujący kod do Global.asax, aby przechwytywać nieobsłużone wyjątki, logować je, a następnie przekazywać kontrolę do ErrorController, aby wyświetlić błędy niestandardowe. Ten kod pochodzi ztutaj:
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));
}
Błąd Application_Error zdecydowanie odpala, ponieważ rejestrowanie działa dobrze, ale zamiast wyświetlać moje niestandardowe strony błędów, otrzymuję te ogólne. Z tytułu wpisu na blogu, z którego pochodzi powyższy kod, zauważam, że używa on Release Candidate 2 frameworka MVC. Czy coś zmieniło się w 1.0, co powoduje, że ostatnia linia kodu nie działa? Jak zwykledziała świetnie na moim komputerze.
Wszelkie sugestie będą bardzo mile widziane.
Edycja: Zapomniałem wspomnieć, że wypróbowałem wszystkie 3 możliwości trybu customErrors w Web.config (Off, On i RemoteOnly). Takie same wyniki niezależnie od tego ustawienia.
Edytuj 2: Próbowałem także z i bez dekoracji [HandleError] w klasach kontrolera.
Aktualizacja: Odkryłem i naprawiłem 404s. Jest sekcja panelu Ustawienia w Go Daddy's Hosting Control Center, w której można kontrolować zachowanie 404, a domyślnie wyświetla się ich ogólna strona i najwyraźniej zastępuje to wszystkie ustawienia Web.config. Moja niestandardowa strona 404 jest teraz wyświetlana zgodnie z przeznaczeniem. Jednak 500s i 503s nadal nie działają. Dostałem kod w HomeController, aby pobrać statyczną wersję tekstową treści, jeśli serwer Sql zgłosi wyjątek w następujący sposób:
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);
}
}
}
Oto kod, który próbuje pobrać zawartość statyczną:
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;
}
Sprawdziłem, że jeśli zmienię ciąg połączenia w celu wygenerowania wyjątku SqlException, kod poprawnie zarejestruje błąd, a następnie przechwyci i wyświetli zawartość statyczną. Ale jeśli zmienię także ścieżkę do statycznego pliku tekstowego w Web.config, aby przetestować wersję 503 Home View, otrzymuję zamiast tego stronę z niczym innym niż „usługa niedostępna”. to jest to! Brak niestandardowego komunikatu 503 z wyglądem i stylem witryny.
Czy ktoś ma jakieś sugestie dotyczące ulepszeń kodu, które mogą pomóc? Czy pomogłoby to dodać różne nagłówki do HttpResponse? Czy może Go Daddy z trudem przejmuje kontrolę nad 503?