在尝试为返回NotFound结果的页面请求显示自定义404错误页面时,我在dotnet剃刀页面Web应用程序中遇到UseStatusCodePagesWithReExecute
的问题。具体来说,如果我从OnGet方法返回NotFound,我会发现相同的请求被再次调用,并且永远不会重新执行提供给中间件的路径。
我正在使用.NET Core 3.0,因此没有尝试使用早期版本或3.1预览。
我已经设法通过简单的复制来复制问题。以下内容将使无效路由重定向到错误页面(例如https://localhost:5001/foo
),但是,路由https://localhost:5001/
将被调用两次,而不重定向到错误页面。
所以我要问的问题是一个bug还是我在这里缺少一些概念?我已经尝试了相关的UseStatusCodePagesWithRedirects
方法,它按照它应该做的方式工作,但是如果可以的话,我真的很想使用ReExecute。
复制
环境:
步骤:
dotnet new webapp -n myapp
。Index.cshtml.cs
OnGet
方法编辑为以下内容: public IActionResult OnGet()
{
return NotFound();
}
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();
});
}
/Error
,而是再次命中断点。谢谢。
答案 0 :(得分:1)
StatusCodePages中间件具有3种显示自定义错误页面的方法,它们是
UseStatusCodePages
,UseStatusCodePagesWithReditects
和UseStatusCodePagesWithReExecute
。如果您希望通过编辑NotFound
Index.cshtml.cs
方法来访问https://localhost:5001/时返回OnGet
的结果,则应使用UseStatusCodePages
来自定义404错误页面,而不是UseStatusCodePagesWithReExecute
。
尽管如此,如果您坚持使用UseStatusCodePagesWithReExecute
,则无需返回真实的NotFound
。 UseStatusCodePagesWithReExecute
用于不存在的资源。访问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。
这是一个工作样本。
编辑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();
});
}
将@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 :(得分:0)
如果你使用
return new NotFoundResult();
代替
return NotFound();
它将使用所需的管道,唯一的缺点是无法传递消息,如果要传递消息,则需要构建自己的中间件来处理这种情况。