2015-06-11 12 views
11

chcę, aby wyświetlić różne komunikaty o błędach dla każdego np kodem stanu:ASP.NET MVC błędy 6 obsługi w oparciu o kod stanu HTTP

  • 400 Bad Request
  • 403.
  • 500 serwera Wewnętrzny błąd
  • 404 Not Found
  • 401.

Jak można Osiągam to w nowych aplikacjach ASP.NET MVC 6? Czy mogę to zrobić za pomocą wbudowanej metody UseErrorHandler?

application.UseErrorHandler("/error"); 

Zauważyłem również, że nawet w przypadku powyższej procedury wprowadzanie nieistniejącego adresu URL, np./this-page-does-not-exist, powoduje brzydką stronę błędu 404 Not Found z IIS. Jak można to załatwić?

W MVC 5 musieliśmy użyć sekcji CustomErrors system.Web dla ASP.NET i, sekcja system.webServer httpErrors w pliku web.config, ale trudno było pracować z nieporęczny, z dużą ilością bardzo dziwne zachowanie. Czy MVC 6 czyni to znacznie prostszym?

Odpowiedz

11

Można użyć do tego celu StatusCodePagesMiddleware. Oto przykład:

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 
{ 
    app.UseStatusCodePagesWithReExecute("/StatusCodes/StatusCode{0}"); 

    app.UseMvcWithDefaultRoute(); 

kontroler, który obsługuje żądania kod stanu:

public class StatusCodesController : Controller 
{ 
    public IActionResult StatusCode404() 
    { 
     return View(viewName: "NotFound"); // you have a view called NotFound.cshtml 
    } 

    ... more actions here to handle other status codes 
} 

Niektóre Uwagi:

  • Sprawdź inne metody przedłużania jak UseStatusCodePagesWithRedirects i UseStatusCodePages innych możliwości.
  • Próbowałem mieć StatusCode jako ciąg zapytania w moim przykładzie, ale wygląda na to, że middleware nie obsługuje ciągów zapytań, ale możesz spojrzeć na kod this i naprawić ten problem.
+1

Uwaga: To lepsze rozwiązanie niż to, które podałem poniżej. –

+0

Ten kod jest wykonywany dla wszystkich żądań. Czy mam rację mówiąc, że zostanie to dodane do delegata akcji, który można przekazać do UseErrorHandler? –

+1

@RehanSaeed: tak, może to być wykonane dla wszystkich żądań, ponieważ musi przechwycić odpowiedzi, aby zweryfikować kod statusu. Nie mam jasności co do twojego drugiego pytania. To jest inne oprogramowanie pośrednie niż "UserErrorHandler". możesz rozwinąć więcej? –

3

Jak mogę to osiągnąć w nowych aplikacjach ASP.NET MVC 6? Czy mogę to zrobić za pomocą wbudowanej metody UseErrorHandler?

Szybka odpowiedź: Nie w eleganckim stylu.

Wyjaśnienie/Alternatywa: Aby rozpocząć pozwala pierwsze spojrzenie na to, co jest rzeczywiście metoda UseErrorHandler robi: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerExtensions.cs#L25 który dodaje następujące middleware: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerMiddleware.csUwaga wiersze 29-78 (metoda invoke)

invoke Metoda jest wykonywana zawsze, gdy przychodzi żądanie (kontrolowane przez lokalizację twojego application.UseErrorHandler("...") w twoim Startup.cs). Tak więc UseErrorHandler jest gloryfikowanym sposobem dodawania niestandardowego oprogramowania pośredniego: middleware = komponent, który może działać na żądanie http.

Teraz z tym tłem, jeśli chcemy dodać własne oprogramowanie pośredniczące do błędów, które różnicuje żądania. Możemy to zrobić, dodając podobne oprogramowanie pośrednie, które jest podobne do domyślnego ErrorHandlerMiddleware, modyfikując następujące linie: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerMiddleware.cs#L48-L51 Dzięki temu podejściu możemy kontrolować ścieżkę przekierowania w oparciu o kod statusu.

W MVC 5 musieliśmy użyć sekcji CustomErrors system.Web dla ASP.NET oraz sekcję system.webServer httpErrors w pliku web.config, ale trudno było pracować z nieporęczny, z dużą ilością bardzo dziwne zachowanie. Czy MVC 6 czyni to znacznie prostszym?

Odpowiedź: To na pewno robi :). Podobnie jak powyższa odpowiedź, poprawka polega na dodaniu oprogramowania pośredniego.Istnieje skrót do dodawania prostego oprogramowania pośredniego poprzez IApplicationBuilder w twoim Startup.cs; Na koniec swojej metodzie Configure można dodać następujące:

app.Run(async (context) => 
{ 
    await context.Response.WriteAsync("Could not handle the request."); 

    // Nothing else will run after this middleware. 
}); 

To będzie działać, ponieważ oznacza to, że osiągnął koniec swojej rurociągu http bez żądania są obsługiwane (ponieważ jest na końcu swojej metodzie Configure w Startup.cs). Jeśli chcesz dodać middleware (w szybki sposób) z możliwością wykonania middleware po ciebie, oto jak:

app.Use(async (context, next) => 
{ 
    await context.Response.WriteAsync("Could not handle the request."); 

    // This ensures that any other middelware added after you runs. 
    await next(); 
}); 

Nadzieja to pomaga!

+0

Przypuszczalnie jest to zamiennik dla części CustomErrors zaledwie web.config i nie będzie działać dla 404 błędów nie znaleziono. W tym celu nadal potrzebowalibyśmy korzystać z httpErrors? –

+1

To również działa na 404 nie znaleziono błędów. 404 występuje, gdy nic nie może obsłużyć żądania. –

0

Działa z różnymi kodami statusu bez określania każdego pojedynczo w kontrolerze.

Startup.cs:

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 
{ 
    app.UseStatusCodePagesWithRedirects("/StatusCodes?statusCode={0}"); 
    app.UseMvcWithDefaultRoute(); 

Kontroler:

public class StatusCodesController : Controller 
    { 
    public IActionResult Index(string statusCode) 
    { 
     if(statusCode == null) statusCode = ""; 
     if(statusCode == "404") return View("Error404"); 
     return View("Index",statusCode); 
    } 

    public IActionResult Test404() { return StatusCode(404); } 
    public IActionResult Test500() { return StatusCode(500); } 

Widok:

@model string 
@{ ViewData["Title"] = Model + " Oops!"; } 

<style> 
    .error-template { 
    padding: 40px 15px; 
    text-align: center; 
    } 

    .error-actions { 
    margin-bottom: 15px; 
    margin-top: 15px; 
    } 

    .error-actions .btn { 
     margin-right: 10px; 
    } 
</style> 

<div class="container"> 
    <div class="row"> 
    <div class="col-md-12"> 
     <div class="error-template"> 
     <h2>Oops!</h2> 
     <h2>@Model Error</h2> 
     <div class="error-details">Sorry, an error has occurred!</div> 
     <div class="error-actions"> 
      <a class="btn btn-primary btn-lg" href="/"><span class="glyphicon glyphicon-home"></span> Take Me Home </a> 
      <a class="btn btn-default btn-lg" href="/Home/ContactUs"><span class="glyphicon glyphicon-envelope"></span> Contact Support </a> 
     </div> 
     </div> 
    </div> 
    </div> 
</div>