2012-04-23 34 views
11

Zacznę od, tak, stworzyliśmy i używamy filtru wyjątków dziedziczącego z ExceptionFilterAttribute. Jest rejestrowany w konfiguracji przy uruchomieniu aplikacji tuż po naszym filtrze tożsamości i działa prawie tak, jak się spodziewano, jeśli wystąpi błąd w naszym interfejsie API.Wyjątek Obsługa interfejsu ASP.NET MVC Web API

W związku z tym szukam sposobu radzenia sobie z błędami, które mają miejsce, zanim dotrą do interfejsu API.

Powód: Nigdy nie chcemy zwrócić błędu HTML YSOD i/lub IIS. ZAWSZE chcemy uderzyć w niestandardowy filtr wyjątków/moduł obsługi, abyśmy mogli poprawnie obsłużyć logowanie i zwrócić odpowiedź JSON dla użytkownika.

W tej chwili, używając Fiddlera, aby złożyć wniosek, mogę dołączyć do procesu w3wp.exe i zobaczyć, że żądanie trafiło w metodę Application_BeginRequest w pliku global.asax. Następnie zwraca po prostu odpowiedź 500. Nigdy nie pęka w kodzie z wyjątkiem lub nie trafia do żadnego z moich punktów przerwania po tym. Wygląda na to, że zwraca błąd IIS. Nigdy nie chcemy, aby tak się stało. Potrzebujemy możliwości wychwycenia wszystkich tych wyjątków "niskiego poziomu", zarejestrowania ich i zwrócenia użytkownikowi czegoś znaczącego.

Czy jest coś, co możemy zrobić, aby poradzić sobie z błędami, co wydaje się uderzać w kod ASP.NET MVC Web API?

+0

To jakoś nie pasuje. Czy gdzieś wyrzucasz wyjątki do biblioteki? Dlaczego po prostu nie złapać wyjątku w kontrolerze i nie zwrócisz widoku błędu według własnego wyboru? –

+1

To jest za pomocą interfejsu API ASP.NET MVC Web, więc nie zwracamy widoków z kontrolerów. Zwracamy odpowiedzi JSON/XML. Wspominam również w moim pytaniu, że potrzebuję sposobu na radzenie sobie z wyjątkami, ZANIM dotrą do kontrolerów. Obecnie mamy wyjątek ExceptionFilter, który łapie wyjątki w dowolnym miejscu, gdy tylko znajdziemy się w kontrolerze, abyśmy nie musieli próbować/łapać przy każdej akcji. – phreak3eb

+0

Nie sądzę, że w pełni rozumiem twoje pytanie. Jakie typy błędów próbujesz dokładnie złapać? – cecilphillip

Odpowiedz

4

Mimo że podoba mi się odpowiedź Darina, nie działa w naszym przypadku, ponieważ ASP.NET MVC Web API framework tłumi/obsługuje wyjątki wewnętrznie i nie rzuca ponownie, aby trafić w metodę Application_Error w pliku Global.asax. Nasze rozwiązanie jest takie.

skończyło się na tworzeniu własnego DelegatingHandler tak:

public class PrincipalHandler : DelegatingHandler 
{ 
    protected const string PrincipalKey = "MS_UserPrincipal"; 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     setAnonymousPrincipal(); 

     request = InitializeIdentity(request); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(r => 
           { 
            // inspect result for status code and handle accordingly 
            return r.Result; 
           }); 
    } 
} 

Następnie dodaje go do HttpConfiguration aby upewnić się, że jest to pierwszy/ostatni obsługi na trafienie. Sposób obsługi procedur w Web API jest hierarchiczny. Więc pierwszy handler, który zostanie trafiony na żądanie, będzie ostatnim treserem, który zostanie trafiony w odpowiedzi. Przynajmniej to jest moje zrozumienie, ktoś może mnie poprawić, jeśli się mylę.

public static void ConfigureApis(HttpConfiguration config) 
{ 
    config.MessageHandlers.Insert(0, new PrincipalHandler()); 
} 

Korzystając z tego podejścia, możemy teraz sprawdzać każdy wynik wracający w odpowiedziach z interfejsu API i kontrolerów internetowych. Dzięki temu możemy obsłużyć każde rejestrowanie, które może wystąpić w wyniku czegoś, co nie zostanie zwrócone zgodnie z naszymi oczekiwaniami. Możemy teraz zmienić treść odpowiedzi, aby serwer IIS nie wstawiał domyślnych stron błędów HTML, jeśli widzi określone kody statusu HTTP.

Jedyny problem jaki mam z tym, i mam nadzieję, że zmienią go w nadchodzącym wydaniu web API, jest to, że nie wysyłają wyjątku z powrotem do zadania zwracanego z base.SendAsync (). Tak więc jedyną informacją, którą musimy przejść jest kod statusu HTTP i staramy się dać rozsądną lub prawdopodobną odpowiedź konsumentowi.

+0

Dla każdego, kto szuka dokumentacji związanej z okablowaniem połączenia z 'config.MessageHandlers.Insert()', jest dostępny [w dokumentacji WebAPI] (http://www.asp.net/web-api/overview/working-with -http/http-obsługi-obsługi). –

+1

Jeśli chcesz mieć globalny moduł obsługi błędów w Web API z dostępnymi pełnymi informacjami o wyjątku, zagłosuj na tę funkcję pod adresem http://aspnetwebstack.codeplex.com/workitem/1001 –

+0

Wygląda to na poręczną odmianę: http: // blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ – CrazyPyro

Powiązane problemy