2015-03-10 13 views
9

Sto provando a creare un'API Web con MVC 6. Tuttavia, quando uno dei metodi del controller genera un errore, il contenuto della risposta è una pagina HTML formattata in modo molto gradevole che sarebbe molto istruttivo se questa fosse un'app MVC. Ma dal momento che questa è un'API, preferirei piuttosto restituire un JSON.Restituzione degli errori JSON dall'API Asp.Net MVC 6

Nota: La mia configurazione è super semplice in questo momento, appena impostazione:

app.UseStaticFiles(); 
    app.UseIdentity(); 

    // Add MVC to the request pipeline. 
    app.UseMvc(); 

Voglio impostare questa funzione universalmente. Esiste un modo "giusto/migliore" per configurarlo in MVC 6 per un'API?

Grazie ...

risposta

13

Un modo per raggiungere lo scenario è quello di scrivere un ExceptionFilter e che catturano i dettagli necessari e impostare il Result per essere un JsonResult.

// Here I am creating an attribute so that you can use it on specific controllers/actions if you want to. 
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute 
{ 
    public override void OnException(ExceptionContext context) 
    { 
     var exception = context.Exception; 
     context.Result = new JsonResult(/*Your POCO type having necessary details*/) 
     { 
      StatusCode = (int)HttpStatusCode.InternalServerError 
     }; 
    } 
} 

È possibile aggiungere questo filtro di eccezione per essere applicabile a tutti i controller. Esempio:

app.UseServices(services => 
{ 
    services.AddMvc(); 
    services.Configure<MvcOptions>(options => 
    { 
     options.Filters.Add(new CustomExceptionFilterAttribute()); 
    }); 
..... 
} 

Si noti che questa soluzione non copre tutti gli scenari ... per esempio, quando viene generata un'eccezione durante la scrittura la risposta da un formattatore.

+0

Quindi gli altri modi che ho visto per fare questo erano: # 1: Override OnActionExecuted in un controller di base. E # 2: app.UseErrorHandler ("/ Home/Errore") per andare a un metodo di controller per gestire gli errori. Entrambi funzionano ma entrambi sembrano un po 'pazzi. Questo approccio sembra migliore, ma nessuno dei tre può gestire un semplice 404, ad esempio a causa di un brutto URL. Questo viene catturato prima che qualcuno di questi calci dentro. C'è un modo per intercettare tutti gli errori? – swannee

+0

Grazie per le informazioni. Non sono sicuro dell'approccio n. 1 e dovrò verificare. L'approccio n. 2 sembra essere una soluzione generica per qualsiasi middleware registrato dopo il middleware ErrorHandler e quando si verifica un'eccezione per la richiesta corrente viene reindirizzato a un URL diverso per gestirlo. L'aspetto del codice sorgente sembra non gestire le eccezioni relative alla scrittura del formattatore. –

+1

E per quanto riguarda la tua domanda sull'acquisizione di 404 risposte. Queste non sono considerate eccezioni in generale, ma se vuoi catturare anche queste, allora alcune opzioni che posso pensare sono: 1) un percorso catch-all registrato alla fine della collezione di rotte che quando viene colpito conferma che nessuna i percorsi precedenti nella tua raccolta di rotte corrispondono e 2) un middleware che si trova prima di MVC, ma il problema è che non puoi distinguere se un 404 restituito da MVC è dovuto a Url errato o diciamo un'azione che restituisce 404 come prodotto con un dato ID non trovato. –

Problemi correlati