2016-08-17 3 views
4

Ich versuche, meine 404s richtig zu funktionieren, aber nicht herausfinden, wie man es richtig macht.Zurück 404 Seite ohne Umleitung

Zunächst stellte ich meinen folgende in meiner statup Configure-Methode:

app.UseMvc(routes => 
{ 
    // routing here 
}); 

app.Use((context, next) => 
{ 
    context.Response.StatusCode = 404; 
    return next(); 
}); 

app.UseStatusCodePagesWithRedirects("/error/{0}"); 

, die zu einer Seite weitergeleitet, wo ich den Fehler zeigte. Die Statuscodes waren jedoch 302 > 200. Ich setze die /error/{code} Aktion, um den relevanten Statuscode zurückzugeben, so jetzt habe ich 302 > 404, die (wegen der Umleitung 302) es so aussehen lässt, als ob die /error/404 Seite nicht existiert (was sie tut).

Ich möchte die Fehlerseite ohne die Umleitung zurückgeben, so dass der Versuch, /doesntexist anzufordern, 404 zurückgibt und die Fehlerseite anzeigt.

Das andere, was ich versuchte, ist app.UseStatusCodePagesWithReExecute("/error/{0}"); zu verwenden, die eine 404 zurückgibt, ohne die URL zu ändern, sondern zeigt nur eine leere Seite statt meine Fehlerseite

+1

Es sieht aus wie Sie die Middleware an die Pipeline in umgekehrter Reihenfolge hinzugefügt haben. MVC sollte immer der letzte in der Pipeline sein, da es sich um eine "terminale" Middleware handelt, was bedeutet, dass eine Anfrage niemals fallen wird. – khellang

+0

Unbehandelte Anfragen (die in MVC keiner bestimmten Route entsprechen) werden definitiv gerade durchlaufen. Wenn es Terminal wäre, würde es nicht auf die Aktion "/ error" umleiten. –

+0

Ja, Sie haben Recht. Es * fällt * für unbehandelte Routen durch: https://github.com/aspnet/Routing/blob/02c92c6f929f1241683a3bb8bad027237f2f679c/src/Microsoft.AspNetCore.Routing/RouterMiddleware.cs#L39. Die Reihenfolge Ihrer Middleware ist jedoch immer noch falsch. Der 'UseStatusCodePages' MW sollte immer vor dem' UseMvc' MW liegen. – khellang

Antwort

9

In meiner app, ich bin es, wie dies zu tun:

// custom 404 and error page - this preserves the status code (ie 404) 
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}"); 

My Homecontroller hat diese Aktion Methode

public IActionResult Error(int statusCode) 
{ 
    if (statusCode == 404) 
    { 
     var statusFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>(); 
     if (statusFeature != null) 
     { 
      log.LogWarning("handled 404 for url: {OriginalPath}", statusFeature.OriginalPath); 
     } 

    } 
    return View(statusCode); 
} 

und meiner Meinung nach ist wie folgt:

@model int 

@{ 
    switch (Model) 
    { 
     case 400: 
      ViewData["Icon"] = "fa fa-ban text-danger"; 
      ViewData["Title"] = "Bad Request"; 
      ViewData["Description"] = "Your browser sent a request that this server could not understand."; 
      break; 
     case 401: 
      ViewData["Icon"] = "fa fa-ban text-danger"; 
      ViewData["Title"] = "Unauthorized"; 
      ViewData["Description"] = "Sorry, but the page requires authentication."; 
     break; 
     case 403: 
      ViewData["Icon"] = "fa fa-exclamation-circle text-danger"; 
      ViewData["Title"] = "Forbidden"; 
      ViewData["Description"] = "Sorry, but you don't have permission to access this page."; 
     break; 
     case 404: 
      ViewData["Icon"] = "fa fa-exclamation-circle text-danger"; 
      ViewData["Title"] = "Page Not Found"; 
      ViewData["Description"] = "Sorry, but the page you were looking for can't be found."; 
      break; 
     case 500: 
     default: 
      ViewData["Icon"] = "fa fa-exclamation-circle text-danger"; 
      ViewData["Title"] = "Unexpected Error"; 
      ViewData["Description"] = "Well, this is embarrassing. An error occurred while processing your request. Rest assured, this problem has been logged and hamsters have been released to fix the problem."; 
      break; 
    } 
} 

<div class="jumbotron text-center"> 
    <header> 
     <h1><span aria-hidden="true" class="@ViewData["Icon"]"></span> @ViewData["Title"]</h1> 
    </header> 
    <p>@ViewData["Description"]</p> 
    <a class="btn btn-primary btn-lg" href="@Url.RouteUrl("/")"><span aria-hidden="true" class="fa fa-home"></span> Site Home</a> 
</div> 

wie @khellang erwähnt, ist die Reihenfolge der Middleware wichtig, und dies sollte sein, bevor app.UseMvc

+0

Danke, das ist im Grunde, was ich hatte, aber wie Sie und @ Khellang vorgeschlagen, es war die Reihenfolge der Middleware, die durcheinander gebracht wurde oben. Prost –

+0

Danke, ich wusste nicht über Statusfeature! Sehr hilfreich! – Dave