显示ASP.NET Core MVC的404 Not Found页面

时间:2015-07-24 09:10:11

标签: c# asp.net iis asp.net-core asp.net-core-mvc

我正在使用下面的中间件设置HTTP状态代码400到599的错误页面。因此访问/error/400会显示400 Bad Request错误页面。

application.UseStatusCodePagesWithReExecute("/error/{0}");

[Route("[controller]")]
public class ErrorController : Controller
{
    [HttpGet("{statusCode}")]
    public IActionResult Error(int statusCode)
    {
        this.Response.StatusCode = statusCode;
        return this.View(statusCode);
    }
}

但是,访问/this-page-does-not-exist会导致通用的IIS 404 Not Found错误页面。

有没有办法处理与任何路由不匹配的请求?如何在IIS接管之前处理此类请求?理想情况下,我想将请求转发给/error/404,以便我的错误控制器可以处理它。

在ASP.NET 4.6 MVC 5中,我们必须使用Web.config文件中的httpErrors部分来执行此操作。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" />
      <error statusCode="404" responseMode="ExecuteURL" path="/error/404/" />
    </httpErrors>
  </system.webServer>
</configuration>

5 个答案:

答案 0 :(得分:4)

我发现的最好的教程之一是:https://joonasw.net/view/custom-error-pages

摘要在这里:

1。 首先添加一个像ErrorController这样的控制器,然后向其中添加此操作:

[Route("404")]
public IActionResult PageNotFound()
{
    string originalPath = "unknown";
    if (HttpContext.Items.ContainsKey("originalPath"))
    {
        originalPath = HttpContext.Items["originalPath"] as string;
    }
    return View();
}

注意:您可以将操作添加到另一个现有的控制器中,例如HomeController

2。 现在添加PageNotFound.cshtml视图。像这样:

@{
    ViewBag.Title = "404";
}

<h1>404 - Page not found</h1>

<p>Oops, better check that URL.</p>

3。 重要的部分在这里。将此代码添加到Startup方法内的Configure类中:

app.Use(async (ctx, next) =>
{
    await next();

    if(ctx.Response.StatusCode == 404 && !ctx.Response.HasStarted)
    {
        //Re-execute the request so the user gets the error page
        string originalPath = ctx.Request.Path.Value;
        ctx.Items["originalPath"] = originalPath;
        ctx.Request.Path = "/error/404";
        await next();
    }
});

请注意,必须先添加它,然后再路由app.UseEndpoints...之类的配置。

答案 1 :(得分:4)

您可以在 asp.net core 中的 EndPoint 中使用回退,如下所示(在 app.UseEndpoints 内)和剃刀页面(NotFound 是页面文件夹中的剃刀页面而不是控制器)

 endpoints.MapRazorPages();
            
 endpoints.MapFallback( context => {
    context.Response.Redirect("/NotFound");
    return Task.CompletedTask;
  });

答案 2 :(得分:3)

基于this SO item,IIS在到达UseStatusCodePagesWithReExecute之前获取404(因此处理它)。

你试过这个:https://github.com/aspnet/Diagnostics/issues/144?它建议终止收到404的请求,以便它不会去IIS处理。以下是添加到Startup中的代码:

app.Run(context =>
{
   context.Response.StatusCode = 404;
   return Task.FromResult(0);
});

这似乎只是一个IIS问题。

答案 3 :(得分:0)

Asp.net 核心 3.1 和 5

在您的 HomeController.cs 中:

public class HomeController : Controller
{
   [Route("/NotFound")]
   public IActionResult PageNotFound()
   {
      return View();
   }
}

Startup.cs > ConfigureServices 方法中:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   app.Use(async (context, next) =>
   {
      await next();
      if (context.Response.StatusCode == 404)
      {
         context.Request.Path = "/NotFound";
         await next();
      }
   });
   
   app.UseHttpsRedirection();
   app.UseStaticFiles();
}

答案 4 :(得分:0)

在处理 500 和 404 错误几个小时后,我已经实施了下面给出的解决方案。

要处理 500 服务器端错误,您可以使用 app.UseExceptionHandler 中间件,但 app.UseExceptionHandler 中间件仅处理未处理的异常,而 404 不是异常。为了处理 404 错误,我设计了另一个自定义中间件,它正在检查响应状态代码,如果它是 404,则将用户返回到我的自定义 404 错误页面。

if (env.IsDevelopment())
   {
       app.UseDeveloperExceptionPage();
   }
   else
   {
       //Hnadle unhandled exceptions 500 erros
       app.UseExceptionHandler("/Pages500");
       //Handle 404 erros
       app.Use(async (ctx, next) =>
       {
           await next();
           if (ctx.Response.StatusCode == 404 && !ctx.Response.HasStarted)
           {
               //Re-execute the request so the user gets the error page
               ctx.Request.Path = "/Pages404";
               await next();
           }
       });
   }

注意:您必须在 app.UseExceptionHandler("/Pages500"); 方法的开头添加 Configure 中间件,以便它可以处理来自所有中间件的异常。自定义中间件可以放在 app.UseEndpoins 中间件之前的任何件,但仍然最好放在 Configure 方法的开头。 /Pages500/Pages404 网址是我的自定义页面,您可以为您的应用程序设计。