Ich habe ein Problem mit benutzerdefinierten Fehlern auf einer ASP.NET MVC App, die ich auf meinem freigegebenen Host bereitgestellt habe. Ich habe einen ErrorController erstellt und den folgenden Code zu Global.asax hinzugefügt, um nicht behandelte Ausnahmen abzufangen, sie zu protokollieren und dann die Steuerung an den ErrorController zu übergeben, um benutzerdefinierte Fehler anzuzeigen. Dieser Code wird von here genommen:ASP.NET MVC App benutzerdefinierte Fehlerseiten nicht in freigegebenen Hosting-Umgebung angezeigt
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 definitiv feuert, weil die Protokollierung gut funktioniert, sondern meine eigenen Fehlerseiten angezeigt wird, bekomme ich die Go Daddy generischen. Aus dem Titel des Blogposts, aus dem der obige Code stammt, bemerke ich, dass er Release Candidate 2 des MVC-Frameworks verwendet. Hat sich in 1.0 etwas geändert, wodurch die letzte Codezeile nicht funktioniert? Wie immer .
Alle Vorschläge werden sehr geschätzt.
Bearbeiten: Vergessen zu erwähnen, dass ich alle 3 Möglichkeiten für den customErrors-Modus in Web.config ausprobiert habe (Aus, Ein und RemoteOnly). Gleiche Ergebnisse unabhängig von dieser Einstellung.
Edit 2: Und ich habe es auch mit und ohne die [HandleError] Dekoration auf den Controller-Klassen versucht.
Update: Ich habe herausgefunden und repariert die 404s. Es gibt einen Abschnitt des Einstellungsfensters im Hosting-Kontrollzentrum von Go Daddy, in dem das Verhalten von 404 gesteuert werden kann. Standardmäßig wird die generische Seite angezeigt. Dies überschreibt offensichtlich alle Einstellungen von Web.config. Meine benutzerdefinierte 404-Seite wird jetzt wie gewünscht angezeigt. 500s und 503 funktionieren jedoch immer noch nicht. Ich habe Code in dem Homecontroller habe eine statische Textversion des Inhalts zu greifen, wenn SQL Server eine Ausnahme auslöst wie folge:
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);
}
}
}
Hier ist der Code ist, das die statischen Inhalte zu holen versucht:
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;
}
Ich habe überprüft, dass, wenn ich die Verbindungszeichenfolge ändere, um eine SqlException zu generieren, der Code den Fehler ordnungsgemäß protokolliert und dann den statischen Inhalt erfasst und anzeigt. Wenn ich aber auch den Pfad zur statischen Textdatei in Web.config ändere, um die 503-Version der Home-Ansicht zu testen, bekomme ich stattdessen eine Seite mit nichts anderem als "Dienst nicht verfügbar". Das ist es. Keine benutzerdefinierte 503-Nachricht mit dem Erscheinungsbild der Website.
Hat jemand irgendwelche Vorschläge zu Verbesserungen am Code, die helfen könnten? Wäre es hilfreich, der HttpResponse verschiedene Header hinzuzufügen? Oder entführt Go Daddy schwerfällig die 503er?
+1 Danke, Bryan. Nach über 2 Stunden Suche hast du mir die Antwort gegeben, die ich brauchte. Es ist so einfach. Ich habe versucht, einen 404 Fehlercode zu setzen, der mir eine Sicherheitsausnahme und "Response.TrySkipIisCustomErrors = true;" gab behoben. –
Das hat mich verrückt gemacht. Ich danke dir sehr. Platzieren von "Response.TrySkipIisCustomErrors = true;" Unmittelbar nach dem Setzen der Response-Codes in meinem Error-Controller funktioniert das für mich. Es war irreführend, weil meine lokale IIS 7-Instanz meine benutzerdefinierten Fehleransichten rendert hat, der Remote-Staging-Server jedoch nicht. = P – NovaJoe
Ich war im selben Boot nach der Anwendung, was in dieser Antwort zur Verfügung gestellt wird: http://Stackoverflow.com/a/7499406/114029. 'Response.TrySkipIisCustomErrors = true;' kommt vom Himmel! :) –