【问题标题】:MVC 6 404 Not Found未找到 MVC 6 404
【发布时间】:2015-04-02 19:42:59
【问题描述】:

我想要一个通用的 404 Not Found 页面 (HTTP 200),而不是获得 HTTP 404 响应。我知道您可以使用

在 MVC 5 中进行设置
<customErrors mode="On">
  <error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>

但我似乎无法弄清楚如何在 MVC 6 中执行此操作。我猜它应该在 UseMvc 路由表或自定义中间件中。

【问题讨论】:

  • 从来不需要这样做,但我很好奇有什么不同,这似乎是有道理的:benfoster.io/blog/aspnet-mvc-custom-error-pages 以一种令人费解的方式。
  • &lt;customErrors&gt; 不起作用吗?在此处查看我的答案(如果相关):stackoverflow.com/questions/28989026/… 如果您使用的是 IIS7+,那么&lt;httpErrors&gt; 是通过网络配置和自定义视图捕获和处理 404 等问题的更好方法。

标签: asp.net-mvc asp.net-core asp.net-core-mvc


【解决方案1】:

Startup.cs:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        // PICK YOUR FLAVOR.

        // app.UseErrorPage(ErrorPageOptions.ShowAll);
        app.UseStatusCodePages(); // There is a default response but any of the following can be used to change the behavior.

        // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
        // app.UseStatusCodePages("text/plain", "Response, status code: {0}");
        // app.UseStatusCodePagesWithRedirects("~/errors/{0}"); // PathBase relative
        // app.UseStatusCodePagesWithRedirects("/base/errors/{0}"); // Absolute
        // app.UseStatusCodePages(builder => builder.UseWelcomePage());
        // app.UseStatusCodePagesWithReExecute("/errors/{0}");
    }
} 

project.json:

"dependencies": {
    "Microsoft.AspNet.Diagnostics": "1.0.0-*",
    // ....
}

请注意,如果您在 IIS(或 azure)上托管,web.config 仍然可以工作,并且在某些托管场景中可能需要它很大。 (应该放在wwwroot文件夹内

【讨论】:

  • 我试过使用UseStatusCodePagesWithReExecute,但它不能处理/this-page-does-not-exist的404。
  • @MuhammadRehanSaeed app.UseStatusCodePagesWithReExecute("/Home/Error/{0}"); 在 beta8 中工作。
  • 顺便提一下,截至目前1.1.0,似乎没有UseErrorPage()扩展方法
【解决方案2】:

您可以使用UseStatusCodePagesWithReExecute 处理 404 错误 但是您需要先在配置管道的末尾设置状态代码。

public void Configure(IApplicationBuilder app)
    {
        app.UseIISPlatformHandler();

        if (string.Equals(_env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))
        {
            app.UseDeveloperExceptionPage();
            app.UseRuntimeInfoPage();
        } else
        {
            app.UseExceptionHandler("/Error");
        }
        app.UseStatusCodePagesWithReExecute("/Error/Status/{0}");

        app.UseStaticFiles();

        app.UseMvc();

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

如果管道中没有任何东西可以处理它(这是您想要的),这会将状态代码设置为 404。

然后,您可以轻松地在控制器中以任何您想要的方式捕获和处理响应。

[Route("error")]
public class ErrorController : Controller
{

[Route("Status/{statusCode}")]
    public IActionResult StatusCode(int statusCode)
    {

            //logic to generate status code response

            return View("Status", model);
    }
}

【讨论】:

  • 谢谢!但是在我的测试中,我不需要在管道末端捕获 404(使用 Core 1.0)
【解决方案3】:

如果有人希望使用 HTML 创建自定义 404 页面,您可以这样做:

Startup.cs

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {        
        app.UseStatusCodePagesWithReExecute("/errors/{0}");
    }
}

project.json

"dependencies": {
    "Microsoft.AspNet.Diagnostics": "1.0.0-*",
    // ....
}

ErrorsController.cs

public class ErrorsController : Controller
{
    // ....

    [Route("/Error/{statusCode}")]
    public IActionResult ErrorRoute(string statusCode)
    {
        if (statusCode == "500" | statusCode == "404")
        {
            return View(statusCode);
        }

        return View("~/Views/Errors/Default.cshtml");
    }
}

这之后剩下的就是在您的错误视图文件夹中创建一个 404.cshtml、500.cshtml 和 Default.cshtml 并根据您的喜好自定义 HTML。

【讨论】:

  • 在启动时你有“/errors/{0}”(复数“errors”)和属性[Route("/Error/{statusCode}")](单数“error”)。它不会起作用。
【解决方案4】:

在Startup类的Configure函数中,调用:

app.UseErrorPage(ErrorPageOptions.ShowAll);

更多产品准备就绪:

    if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))
    {
        app.UseBrowserLink();
        app.UseErrorPage(ErrorPageOptions.ShowAll);
        app.UseDatabaseErrorPage(DatabaseErrorPageOptions.ShowAll);
    }
    else
    {
        // Add Error handling middleware which catches all application specific errors and
        // send the request to the following path or controller action.
        app.UseErrorHandler("/Home/Error");
    }

【讨论】:

    【解决方案5】:

    有一个名为 StatusCodePagesMiddleware 的中间件,我相信它是在 Beta3 之后添加的。

    示例:https://github.com/aspnet/Diagnostics/blob/dev/samples/StatusCodePagesSample/Startup.cs

    【讨论】:

    • 我认为它在诊断中,但我不确定。
    • 我试过使用UseStatusCodePagesWithReExecute,但它不能处理/this-page-does-not-exist的404。
    【解决方案6】:

    如果您有一个标准的 ASP.NET 5 Web 应用程序模板项目,您可以获得一个非常好的解决方案,该解决方案可以在提供您选择的 cshtml 文件的同时处理保持错误状态代码。

    Startup.cs,在Configure方法中

    替换

    app.UseExceptionHandler("/Error");
    

    app.UseStatusCodePagesWithReExecute("/Home/Errors/{0}");
    

    然后删除以下包罗万象:

    app.Run(async (context) => 
    { 
       var logger = loggerFactory.CreateLogger("Catchall Endpoint"); 
       logger.LogInformation("No endpoint found for request {path}", context.Request.Path); 
       await context.Response.WriteAsync("No endpoint found - try /api/todo."); 
    });
    

    HomeController.cs

    将当前的Error 方法替换为以下方法:

    public IActionResult Errors(string id) 
    { 
      if (id == "500" | id == "404") 
      { 
        return View($"~/Views/Home/Error/{id}.cshtml"); 
      }
    
      return View("~/Views/Shared/Error.cshtml"); 
    }
    

    这样您就可以添加您认为用户可以从中受益的错误文件(而搜索引擎等仍然获得正确的状态代码)

    现在在~Views/Home 文件夹中添加一个名为Error 的文件夹 创建两个.cshtml 文件。将第一个命名为404.cshtml,将第二个命名为500.cshtml

    给他们一些有用的内容,然后启动应用程序并编写类似http://localhost:44306/idonthaveanendpointhere 的内容并确认设置正常。

    同时按 F12 开发者工具,确认状态码为 404。

    【讨论】:

      猜你喜欢
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 2023-03-11
      • 2012-09-15
      • 2017-01-27
      相关资源
      最近更新 更多