2012-10-22 11 views
8

c'è un modo di cambiare il comportamento del Web Api di default per i messaggi di errore, come ad esempio:asp.net Web Api - Messaggi di errore di default

GET /trips/abc 

risponde con (parafrasato):

HTTP 500 Bad Request 

{ 
    "Message": "The request is invalid.", 
    "MessageDetail": "The parameters dictionary contains a null entry for parameter 'tripId' of non-nullable type 'System.Guid' for method 'System.Net.Http.HttpResponseMessage GetTrip(System.Guid)' in 'Controllers.TripController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter." 
} 

I Vorrei evitare di fornire queste informazioni piuttosto dettagliate sul mio codice e sostituirlo con qualcosa del tipo:

HTTP 500 Bad Request 
{ 
    error: true, 
    error_message: "invalid parameter" 
} 

Sarei in grado di farlo all'interno dell'UserController, ma l'esecuzione del codice non è neanche lontanissima.

edit:

Ho trovato un modo per rimuovere messaggi di errore dettagliati dall'uscita, utilizzando questa riga di codice in Global.asax.cs:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = 
IncludeErrorDetailPolicy.LocalOnly; 

Ciò produce un messaggio come questo :

{ 
    "Message": "The request is invalid." 
} 

che è meglio, ma non è esattamente quello che voglio - abbiamo specificato una serie di codici di errore numerici, che sono mappati al dettaglio i messaggi di errore sul lato client. Vorrei uscita solo il codice di errore appropriato (che io sono in grado di selezionare prima uscita, preferibilmente da vedere che tipo di eccezione si è verificato), ad esempio:

{ error: true, error_code: 51 } 

risposta

7

si potrebbe desiderare di mantenere la forma di i dati come tipo HttpError anche se si desidera nascondere informazioni dettagliate sull'eccezione effettiva. Per fare ciò, è possibile aggiungere un DelegatingHandler personalizzato per modificare l'HttpError che viene lanciato dal servizio.

Ecco un esempio di come la DelegatingHandler potrebbe essere simile:

public class CustomModifyingErrorMessageDelegatingHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) => 
     { 
      HttpResponseMessage response = responseToCompleteTask.Result; 

      HttpError error = null; 
      if (response.TryGetContentValue<HttpError>(out error)) 
      { 
       error.Message = "Your Customized Error Message"; 
       // etc... 
      } 

      return response; 
     }); 
    } 
} 
+0

Perfetto, Grazie! – doque

+3

Se ti chiedi dove aggiungerlo, può essere aggiunto chiamando 'config.MessageHandlers.Add (new YourDelegatingHandler())', di solito nel metodo 'Register (HttpConfiguration config)' nella tua logica di avvio. –

+0

Invece di sostituire il contenuto della risposta dopo che è stato creato, non dovremmo piuttosto personalizzare la classe/servizio che è responsabile della creazione di quella risposta in primo luogo? – dgaspar

2

risposta di Maggie ha lavorato anche per me. Grazie per la pubblicazione!

Volevo solo alcuni bit al suo codice per ulteriori chiarimenti:

HttpResponseMessage response = responseToCompleteTask.Result; 
HttpError error = null; 

if ((!response.IsSuccessStatusCode) && (response.TryGetContentValue(out error))) 
{ 
    // Build new custom from underlying HttpError object. 
    var errorResp = new MyErrorResponse(); 

    // Replace outgoing response's content with our custom response 
    // while keeping the requested MediaType [formatter]. 
    var content = (ObjectContent)response.Content; 
    response.Content = new ObjectContent(typeof (MyErrorResponse), errorResp, content.Formatter); 
} 

return response; 

Dove:

public class MyErrorResponse 
    { 
     public MyErrorResponse() 
     { 
      Error = true; 
      Code = 0; 
     } 

     public bool Error { get; set; } 
     public int Code { get; set; } 
    }