2011-02-03 21 views
5

Ho sofferto un paio di giorni con la gestione degli errori in MVC. Non ho ancora capito bene. (Ho anche letto la maggior parte delle domande qui a SO e su Google fino a quando le mie dita sanguinare)Gestione degli errori in MVC

Quello che voglio fare:

  1. utilizzare lo standard [Authorize] attributo
  2. reindirizzare tutti gli errori a mio errore controller (anche non autorizzato)
  3. Avere una azione per errore HTTP nel mio error controller.

Quello che non voglio fare:

  1. Mettere il [ErrorHandler] su tutti i miei controllori (può essere utilizzato sul mio regolatore di base)?
  2. Utilizzare un attributo Autorizza personalizzato.

In realtà, potrei fare qualsiasi cosa necessaria (inclusa la lista NOT) fino a quando ho # 1-3 funzionante.

Quello che ho provato:

  1. Utilizzando Application_Error
  2. Utilizzando Controller.HandleUnknownAction
  3. Utilizzando Controller.OnException
  4. Utilizzando [ErrorHandler] sul mio controller
  5. Accensione/spegnimento CustomErrors nel web.config

Indovinate ho bisogno di una combinazione di quelli o forse qualcos'altro?

risposta

2

È possibile utilizzare un filtro personalizzato, estendere semplicemente ErrorHandlerAttribute e renderlo consapevole del proprio controller degli errori. Di aggiungerlo come filtro globale all'interno Application_Start:

GlobalFilters.Filters.Add(new CustomAErrorHandlerAttribute()); 
4

si potrebbe anche gestire tutta la tua logica errore nel Application_Error del vostro Global.asax.cs e poi instradarli basa la dinamica dei diversi codici di stato HTTP:

protected void Application_Error(object sender, EventArgs e) 
{ 
    var ex = Server.GetLastError().GetBaseException(); 

    var routeData = new RouteData(); 

    if (ex.GetType() == typeof(HttpException)) 
    { 
     var httpException = (HttpException)ex; 

     switch (httpException.GetHttpCode()) 
     { 
      case 401: 
       routeData.Values.Add("action", "NotAuthorized"); 
       break; 
      case 403: 
       routeData.Values.Add("action", "NotAuthorized"); 
       break; 
      case 404: 
       routeData.Values.Add("action", "PageNotFound"); 
       break; 
      default: 
       routeData.Values.Add("action", "GeneralError"); 
       break; 
     } 
    } 
    else 
    { 
     routeData.Values.Add("action", "GeneralError"); 
    } 

    routeData.Values.Add("controller", "Error"); 
    routeData.Values.Add("error", ex); 

    IController errorController = new ErrorController(); 
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); 
} 

sembra che il 401 non gettare necessaria una HttpException così si vuole gestire manualmente che per adattarsi alla logica:

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    if (Context.Response.StatusCode == 401) 
    { 
     throw new HttpException(401, "You are not authorised"); 
    } 
} 

E sì, i controller ereditano gli attributi dal tuo controller di base.

+0

provato. Non viene chiamato per il 401. Non ho idea del perché. – jgauffin

+0

Non ho provato quello per un 401, ma secondo questa risposta (http://stackoverflow.com/questions/1679881/asp-net-mvc-user-friendly-401-error) dovrebbe lanciare un 'HttpException' come bene. –

+0

Ah, potrebbe essere necessario controllare 'Context.Response.StatusCode == 401' in 'Application_EndRequest()' e quindi lanciare 'HttpException (401," Non sei autorizzato ")' da solo. –