UseStatusCodePagesWithReExecute执行两次原始请求,对NotFound结果没有错误响应

时间:2019-12-02 16:32:49

标签: asp.net-core razor-pages

在尝试为返回NotFound结果的页面请求显示自定义404错误页面时,我在dotnet剃刀页面Web应用程序中遇到UseStatusCodePagesWithReExecute的问题。具体来说,如果我从OnGet方法返回NotFound,我会发现相同的请求被再次调用,并且永远不会重新执行提供给中间件的路径。

我正在使用.NET Core 3.0,因此没有尝试使用早期版本或3.1预览。

我已经设法通过简单的复制来复制问题。以下内容将使无效路由重定向到错误页面(例如https://localhost:5001/foo),但是,路由https://localhost:5001/将被调用两次,而不重定向到错误页面。

所以我要问的问题是一个bug还是我在这里缺少一些概念?我已经尝试了相关的UseStatusCodePagesWithRedirects方法,它按照它应该做的方式工作,但是如果可以的话,我真的很想使用ReExecute。

复制

环境:

  • Windows 10
  • dotnet核心3.0
  • Chrome浏览器和边缘浏览器(未尝试使用其他浏览器)-因为没有重新提交,所以无论如何都不要认为这是浏览器问题。

步骤:

  1. 创建模板剃刀项目dotnet new webapp -n myapp
  2. Index.cshtml.cs OnGet方法编辑为以下内容:
        public IActionResult OnGet()
        {
            return NotFound();
        }
  1. 编辑Startup.cs并在Configure方法的if / else代码块之后添加app.UseStatusCodePagesWithReExecute("/Error");,如下所示:
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            // Added this line
            app.UseStatusCodePagesWithReExecute("/Error");

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
  1. 在第一行的OnGet处放置一个断点(假设VSCode或Visual Studio 2019)。
  2. 运行调试和F5,直到第一个请求到达索引页面。不会重定向到/Error,而是再次命中断点。
  3. 再次按F5键,然后浏览器将显示其标准404而不是错误页面。

谢谢。

2 个答案:

答案 0 :(得分:1)

StatusCodePages中间件具有3种显示自定义错误页面的方法,它们是 UseStatusCodePagesUseStatusCodePagesWithReditectsUseStatusCodePagesWithReExecute。如果您希望通过编辑NotFound Index.cshtml.cs方法来访问https://localhost:5001/时返回OnGet的结果,则应使用UseStatusCodePages来自定义404错误页面,而不是UseStatusCodePagesWithReExecute

尽管如此,如果您坚持使用UseStatusCodePagesWithReExecute,则无需返回真实的NotFoundUseStatusCodePagesWithReExecute用于不存在的资源。访问https://localhost:5001/any-non-exisisting-page后,它将抛出404,然后重新执行针对您自己的错误页面的请求。但这不是NotFound方法的替代。同时,在使用UseStatusCodePagesWithReExecute时要注意一些条件和限制,您可以参考本文:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-3.1

这是一个工作样本。

  1. 编辑Startup.cs配置方法,如下所示:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
        //app.UseDeveloperExceptionPage();
        }
        else
        {
       // app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for 
        production scenarios, see https://aka.ms/aspnetcore-hsts.
       // app.UseHsts();
        }
    
       //app.UseStatusCodePages();
        app.UseStatusCodePagesWithReExecute("/Error", "?code={0}");
       // app.UseHttpsRedirection();
    
        app.UseStaticFiles();
    
        //app.UseStatusCodePagesWithRedirects("/Error");
    
        app.UseRouting();
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    
    }
    
  2. 将@page“ {code?}”添加到Error.cshtml:

@page "{code?}"
@model ErrorModel
@{
    ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h1 class="text-danger">Status Code: @Model.ErrorStatusCode</h1>

<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
    <p>
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
    </p>
}

<h3>Development Mode</h3>
<p>
    Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
    It can result in displaying sensitive information from exceptions to end users.
    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
    and restarting the app.
</p>

  1. 访问Edge中不存在的页面https://localhost:52602/hhh时,浏览器将显示以下页面:

enter image description here

答案 1 :(得分:0)

如果你使用

return new NotFoundResult();

代替

return NotFound();

它将使用所需的管道,唯一的缺点是无法传递消息,如果要传递消息,则需要构建自己的中间件来处理这种情况。