2016-11-15 23 views
7

Mam podstawową aplikację asp.net. Implementacja metody configure przekierowuje użytkownika na stronę "Błąd", gdy istnieje wyjątek (w środowisku nie deweloperskim).Obsługa wyjątków w rdzeniu asp.net?

Działa to jednak tylko wtedy, gdy wyjątek występuje wewnątrz kontrolera. Jeśli wystąpi wyjątek poza sterownikiem, na przykład w moim niestandardowym oprogramowaniu pośrednim, to użytkownik nie zostanie przekierowany na stronę błędu.

Jak mogę przekierować użytkownika do strony "Błąd", jeśli w oprogramowaniu pośredniczącym występuje wyjątek.

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     app.UseApplicationInsightsRequestTelemetry(); 

     if (env.IsDevelopment()) 
     { 
      app.UseDeveloperExceptionPage(); 
      app.UseBrowserLink(); 
     } 
     else 
     { 
      app.UseExceptionHandler("/Home/Error"); 
     } 

     app.UseApplicationInsightsExceptionTelemetry(); 

     app.UseStaticFiles(); 
     app.UseSession(); 
     app.UseMyMiddleware(); 

     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
     }); 
    } 

Update 1
I uaktualniony kod powyżej z następujących dwóch linii, które zostały brakuje w początkowym poście.

 app.UseSession(); 
     app.UseMyMiddleware(); 

Również znalazłem dlaczego app.UseExceptionHandler nie był w stanie przekierować do strony błędu.
Gdy istnieje wyjątek w moim kodzie oprogramowania pośredniego, app.UseExceptionHandler("\Home\Error") jest przekierowywane do \Home\Error zgodnie z oczekiwaniami; ale ponieważ jest to nowe żądanie, moje oprogramowanie pośrednie było ponownie uruchamiane i ponownie zgłaszane wyjątek.
Tak, aby rozwiązać ten problem zmieniłem middleware wykonać tylko if context.Request.Path != "/Home/Error"

Nie jestem pewien, czy to jest prawidłowy sposób, aby rozwiązać ten problem, ale swoją pracę.

+0

Gdzie w tym przykładzie jest Twoje niestandardowe oprogramowanie pośredniczące? Myślę, że ** "UseExeptionHandler" powinien być w stanie obsłużyć to, ale twoje oprogramowanie pośrednie musi zostać zarejestrowane ** po ** it. – Tseng

Odpowiedz

5

Powinieneś napisać własne oprogramowanie pośrednie, aby obsłużyć niestandardową obsługę wyjątków. Upewnij się, że dodasz go do początku (pierwszy, jeśli to możliwe) stosu pośredniego, ponieważ wyjątki w oprogramowaniu pośrednim, które są "wcześniej" w stosie, nie będą obsługiwane.

Przykład:

public class CustomExceptionMiddleware 
{ 
    private readonly RequestDelegate _next; 

    public CustomExceptionMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     try 
     { 
      await _next.Invoke(context); 
     } 
     catch (Exception e) 
     { 
      // Handle exception 
     } 
    } 
} 
+1

'Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware' robi dokładnie to samo, co sugerujesz. To oprogramowanie pośrednie przekierowuje do podanej ścieżki incase of exception. Możesz zobaczyć kod https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNetCore.Diagnostics/ExceptionHandler/ExceptionHandlerMiddleware.cs – LP13

5

można wykorzystywać do obsługi wyjątków UseExceptionHandler(), umieścić ten kod w swoim Startup.cs.

UseExceptionHandler może być używany do obsługi wyjątków na całym świecie. Możesz uzyskać wszystkie szczegóły obiektu wyjątku, takie jak Stack Trace, Wewnętrzny wyjątek i inne. A potem możesz pokazać je na ekranie. Here

Tutaj można przeczytać więcej na temat tego oprogramowania pośredniczącego diagnostycznego i znaleźć sposób korzystania IExceptionFilter i tworząc własną klasę obsługi wyjątku.

app.UseExceptionHandler(
       options => 
       { 
        options.Run(
         async context => 
         { 
          context.Response.StatusCode = (int) HttpStatusCode.InternalServerError; 
          context.Response.ContentType = "text/html"; 
          var ex = context.Features.Get<IExceptionHandlerFeature>(); 
          if (ex != null) 
          { 
           var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace}"; 
           await context.Response.WriteAsync(err).ConfigureAwait(false); 
          } 
         }); 
       } 
      ); 

Trzeba również usunąć ustawienie domyślne jak UseDeveloperExceptionPage(), jeśli używasz go, to zawsze pokazuje domyślną stronę błędu.

if (env.IsDevelopment()) 
     { 
      //This line should be deleted 
      app.UseDeveloperExceptionPage(); 
      app.UseBrowserLink(); 
     } 
     else 
     { 
      app.UseExceptionHandler("/Home/Error"); 
     } 
+0

Przeszedłem ten artykuł wcześniej. Jednak wydaje mi się, że problem występuje zawsze, gdy ustawisz response.StatusCode na 500, przeglądarka nie wyświetla 'html', który wysyła serwer, zamiast tego przeglądarka pokazuje swoją własną stronę błędu dla kodu 500. W skrzypce widzę, że ciało odpowiedzi ma komunikat o błędzie, że serwer wysyła, ale przeglądarka nie pokazuje tego komunikatu o błędzie. – LP13

+0

Po prostu usuń z aplikacji startup.cs.UżycieDeveloperExceptionPage(); –

+0

btw Stworzyłem także niestandardowy atrybut filtru wyjątków, który pochodzi z 'ExceptionFilterAttribute'. Dba o wszystkie wyjątki wewnątrz kontrolera. Zamierzamwdrożyć obsługę wyjątków w oprogramowaniu pośredniczącym. Nawet jeśli obsługuję globalnie używając 'app.UżycieExceptionHandler' lub tworzę własne oprogramowanie pośrednie do obsługi wyjątków, to nie przekierowuję użytkownika do widoku błędu. – LP13