2014-04-24 20 views
25

Mam webapi działający na serwerze IIS7.5. Ma 3 kontrolery, a wszystkie 3 mogą być używane do uzyskiwania dostępu do webapi z połączeń w mojej aplikacji.Komunikat wyjątku HTTPError nie jest wyświetlany, gdy program webapi jest uruchamiany na serwerze, a jest uruchamiany lokalnie.

Wystąpił błąd, gdy moja klasa bazowa dla mojego kontrolera ujawniała swoje funkcje jako publiczne, a nie chronione. To spowodowało, że serwer wygenerował błąd serwera wewnętrznego 500 (z powodu niepoprawnego wygenerowania wyjątku "znaleziono wiele działań pasujących do żądania"). Zajęło mi to trochę czasu, ponieważ nigdy nie uruchomiłem logowania z mojego webapi. Od tego pojedynku here odkryłem, że błąd występujący miał miejsce zanim funkcja Application_Error złapie go, aby go zarejestrować. Więc dodałem poniższy kod do mojego pliku global.asax mojego webapi i mogę teraz rejestrować takie błędy.

ALE, mój problem teraz, gdy powoduję błąd serwera wewnętrznego 500 dokładnie jak wyżej, na mojej lokalnej maszynie, na której uruchomiłem moją webapi, otrzymuję dziennik dokładnie tak, jak chcę go zobaczyć za pomocą "wyjątku" z "wielu akcji" zostały znalezione, które pasują do żądania "określona jako przyczyna błędu wewnętrznego serwera. Ale kiedy wdrożę ten dokładny kod na serwerze i użyję stamtąd webapi, mój dziennik wyświetli tylko "Wiadomość": "Wystąpił błąd" i nie pokazuje mi "Wyjątku", chociaż widzę, że wyjątek jest bycie wyrzucanym za pomocą PerfView. Po prostu muszę mieć dzienniki serwera, aby wyświetlały te same informacje, które wyświetla mój log lokalny.

public class ResponseExceptionTrapper : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(
     HttpRequestMessage request, 
     CancellationToken cancellationToken) 
    { 
     return base 
      .SendAsync(request, cancellationToken) 
      .ContinueWith(response => 
      { 
       var result = response.Result; 
       if (!result.IsSuccessStatusCode) 
       { 
        var exceptionResult = string.Format(
         "Response exception: \r\n Path({0}) \r\n Status({1}) \r\n", 
         request.RequestUri, 
         result.StatusCode); 

        if (result.Content != null) 
        { 
         var exceptionReadTask = 
           result.Content.ReadAsStringAsync(); 

         exceptionReadTask.Wait(); 
         exceptionResult += "Message:" + 
              exceptionReadTask.Result; 

        } 

        // Do something appropriate with exceptionResult 
        exceptionResult.Log(); 
       } 

       return result; 
      }, cancellationToken); 
    } 
} 

Server Log Przykład:

Timestamp: 4/24/2014 12:24:40 PM 
Message: Timestamp: 4/24/2014 4:24:40 PM 
Message: Response exception: 
Path(http://webserver/CreditReporting/Api/RetrieveQueuedPullCreditReport) 
Status(InternalServerError) 
Message:{"Message":"An error has occurred."} 

lokalnym dzienniku Przykład:

Timestamp: 4/24/2014 12:03:16 PM 
Message: Timestamp: 4/24/2014 4:03:16 PM 
Message: Response exception: 
Path(http://localhost:XXXXX/Api/RetrieveQueuedPullCreditReport) 
Status(InternalServerError) 
Message: 
    {"Message":"An error has occurred.", 
    "ExceptionMessage":"Multiple actions were found that match the request: 
    \r\nSystem.Threading.Tasks.Task`1[ 
Our.WebServices.CreditReporting.Contracts.RetrieveQueuedPullCreditReportResponse] Post 
+0

Spróbuj również zarejestrować wewnętrzny wyjątek. Nie wiem, dlaczego powinien on być inny w IIS, ale podejrzewam, że faktycznym wyjątkiem może być wewnętrzny wyjątek. Należy zauważyć, że wyjątek InnerException może mieć wartość null, więc upewnij się, że Twój kod rejestrowania sprawdza to również przed jego zapisaniem (w przeciwnym razie kod wygeneruje wyjątek podczas próby zalogowania ...) –

+0

Nie jestem pewien, czy istnieje sposób dostępu do wewnętrzny wyjątek od sposobu napisania tego kodu. Wynik.Content (obiekt HTTPContent) faktycznie nie zawiera wyjątku. – cookiekitty

Odpowiedz

47

Okazało się, że to musiała być włączona w GlobalConfiguration dla WebAPI samego:

1: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly; 
2: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; 
3: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never; 

Akt serwera ually określa, ile szczegółów ma wyświetlić, domyślnie jest to LocalOnly.

Nasza metoda logowania nie jest uważana za lokalną, chyba dlatego, że nie jest wbudowana w samo API, ale dlatego, że znajduje się we współdzielonej bibliotece DLL między wieloma interfejsami API.

znalazłem this artykuł będzie bardzo pomocne.

2

użyłem tego:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
      = IncludeErrorDetailPolicy.Always; 

w Global API i to uda.

Powiązane problemy