2012-10-22 18 views
8

Czy istnieje sposób na zmianę domyślnego zachowania Web API dla komunikatów o błędach, takich jak:asp.net Web API - domyślne komunikaty o błędach

GET /trips/abc 

odpowiada (parafrazą):

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 "Nie chcę podawać tej dosyć szczegółowej informacji o moim kodzie, a zamiast tego zastąpić ją czymś podobnym:

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

Byłbym w stanie to zrobić wewnątrz kontrolera UserController, ale wykonanie kodu nawet nie posunąłoby się tak daleko.

edit:

Znalazłem sposób usuwania szczegółowe komunikaty o błędach z wyjścia, za pomocą tego wiersza kodu w Global.asax.cs:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = 
IncludeErrorDetailPolicy.LocalOnly; 

To daje taki komunikat :

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

co jest lepsze, jednak nie jest to dokładnie to, co chcę - Mamy określony szereg numerycznych kodów błędów, które są sporządzane na szczegółowe komunikaty o błędach po stronie klienta. Chciałbym tylko wyświetlamy odpowiedni kod błędu (które jestem w stanie wybrać przed wyjściem, a najlepiej przez widząc jaką wyjątek wystąpił), na przykład:

{ error: true, error_code: 51 } 

Odpowiedz

7

Może chcesz zachować kształt dane jako typ HttpError, nawet jeśli chcesz ukryć szczegółowe informacje o faktycznym wyjątku. Aby to zrobić, możesz dodać niestandardowy DelegatingHandler, aby zmodyfikować HttpError, który powoduje twoja usługa.

Oto przykład tego, jak może wyglądać DelegatingHandler:

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

Perfect, Thanks! – doque

+3

Jeśli zastanawiacie się, gdzie go dodać, można go dodać, wywołując 'config.MessageHandlers.Add (new YourDelegatingHandler())', zwykle w metodzie 'Register (HttpConfiguration config)' w logice uruchamiania. –

+0

Zamiast zastępować treść odpowiedzi po jej zbudowaniu, czy raczej nie powinniśmy raczej dostosowywać klasę/usługę, która jest odpowiedzialna za budowanie tej odpowiedzi w pierwszej kolejności? – dgaspar

2

odpowiedź Maggie pracował dla mnie. Dzięki za publikację!

Chciałem tylko niektórych bitów do jej kodu dla dodatkowych wyjaśnień:

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; 

Gdzie:

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

     public bool Error { get; set; } 
     public int Code { get; set; } 
    } 
Powiązane problemy