Ho riscontrato un problema con errori personalizzati su un'app di ASP.NET MVC che ho distribuito sul mio host condiviso. Ho creato un ErrorController e aggiunto il seguente codice a Global.asax per rilevare eccezioni non gestite, registrarle e quindi trasferire il controllo a ErrorController per visualizzare errori personalizzati. Questo codice è tratto da here:Pagine di errore personalizzate dell'applicazione ASP.NET MVC non visualizzate nell'ambiente di hosting condiviso
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 è sicuramente sparare perché la registrazione funziona bene, ma invece di visualizzare le mie pagine di errore personalizzate, ottengo quelli generici Go Daddy. Dal titolo del post sul blog tratto dal codice sopra, ho notato che utilizza Release Candidate 2 del framework MVC. Qualcosa è cambiato in 1.0 che rende l'ultima riga di codice non funziona? Come al solito è works great on my machine.
Qualsiasi suggerimento sarà molto apprezzato.
Modifica: Ho dimenticato di aver provato tutte e 3 le possibilità per la modalità CustomErrors in Web.config (Off, On e RemoteOnly). Stessi risultati indipendentemente da questa impostazione.
Edit 2: E ho anche provato con e senza la decorazione [HandleError] sulle classi Controller.
Aggiornamento: ho capito e risolto il 404s. C'è una sezione del pannello Impostazioni nel Centro di controllo hosting di Go Daddy in cui è possibile controllare il comportamento 404 e l'impostazione predefinita è mostrare la pagina generica, e apparentemente questo sostituisce qualsiasi impostazione di Web.config. Quindi la mia pagina 404 personalizzata ora sta mostrando come previsto. Tuttavia, 500 e 503 non funzionano ancora. Ho codice nella HomeController per afferrare una versione di testo statico del contenuto se SQL Server genera un'eccezione come segue:
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);
}
}
}
Ecco il codice che tenta di recuperare il contenuto statico:
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;
}
Ho verificato che se cambio la stringa di connessione per generare una SqlException, il codice registra correttamente l'errore e quindi cattura e visualizza il contenuto statico. Ma se cambio anche il percorso del file di testo statico in Web.config per testare la versione 503 della Home View, quello che ottengo è una pagina con nient'altro che "servizio non disponibile". Questo è tutto. Nessun messaggio 503 personalizzato con l'aspetto grafico del sito.
Qualcuno ha suggerimenti sui miglioramenti del codice che potrebbero essere utili? Sarebbe utile aggiungere intestazioni diverse a HttpResponse? O è Go Daddy che dirotta pesantemente i 503?
+1 Grazie, Bryan. Dopo più di 2 ore di ricerca mi hai dato la risposta di cui avevo bisogno. È così semplice. Stavo cercando di impostare un codice di errore 404 che mi stava dando un'eccezione di sicurezza e "Response.TrySkipIisCustomErrors = true;" aggiustato. –
Questo mi stava facendo impazzire. Grazie mille. Inserimento "Response.TrySkipIisCustomErrors = true;" immediatamente dopo aver impostato i codici di risposta nel mio controller degli errori è ciò che ha funzionato per me. Era fuorviante perché la mia istanza locale di IIS 7 stava visualizzando le mie visualizzazioni degli errori personalizzate, ma il server di gestione remota non lo era. = P – NovaJoe
Ero nella stessa barca dopo aver applicato ciò che viene fornito in questa risposta: http://stackoverflow.com/a/7499406/114029. 'Response.TrySkipIisCustomErrors = true;' viene dal cielo! :) –