[英]UseStatusCodePagesWithReExecute shows blank page
I've been trying to use the UseStatusCodePagesWithReExecute
method to show a page that shows customized messages per status code on the application I'm trying to make with ASP.NET Core 3.0我一直在尝试使用
UseStatusCodePagesWithReExecute
方法来显示一个页面,该页面根据我尝试使用 ASP.NET Core 3.0 创建的应用程序上的状态代码显示自定义消息
I've followed the instructions on this website , but right now, if I try to test this by accessing a non-existant webpage, a blank page shows up, and the code doesn't pass through the OnGet
method on the Razor Page I want to be shown (I used breakpoints).我已按照此网站上的说明进行操作,但是现在,如果我尝试通过访问一个不存在的网页来对此进行测试,则会显示一个空白页面,并且代码不会通过 Razor 页面上的
OnGet
方法我想要显示(我使用了断点)。
However, I am able to get the status page to show by accessing manually the page on my browser using the /Status/404
URI.但是,我可以通过使用
/Status/404
URI 手动访问浏览器上的页面来显示状态页面。
On the startup file, I've added the required lines, as shown in the tutorial.在启动文件中,我添加了所需的行,如教程中所示。
// Startup.cs
public static void Configure(IApplicationBuilder app,
IWebHostEnvironment env,
IHostApplicationLifetime appLifetime)
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePagesWithReExecute("/Status/{0}");
app.UseExceptionHandler("/Status");
// Irrelevant code below
}
The status model contains a OnGet
method that takes the code number as a parameter状态模型包含一个
OnGet
方法,该方法将代码编号作为参数
// Status.cshtml.cs
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusModel : PageModel
{
public void OnGet(string? code = null)
{
if (null == code)
code = HttpContext.Response.StatusCode.ToString();
PageTitle = $"HTTP status {code}";
StatusNumber = code;
if (code.CompareTo("404") == 0)
{
StatusName = "Not found";
StatusDescription = "The requested page was not found.";
}
else
{
StatusName = "Unknown error";
StatusDescription = "An unknown error occurred.";
}
}
}
The status view is quite simple:状态视图非常简单:
@page "{code?}"
@model StatusModel
@{
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@Model.PageTitle</title>
</head>
<body>
<div>
<h1>@Model.StatusNumber</h1>
<h2>@Model.StatusName</h2>
<h2>@Model.StatusDescription</h2>
</div>
<p>RID: @Model.RequestId</p>
</body>
</html>
On the output console, I can see that indeed the application noticed that it caught the 404, but it doesn't appear to do anything:在输出控制台上,我可以看到应用程序确实注意到它捕获了 404,但它似乎没有做任何事情:
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
Executed page /Index in 225.4469ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/Index'
Is there something that's changed when passing from ASP.NET Core 2.2 to 3.0 that I forgot to edit / add to make this work, or is this already supposed to work?从 ASP.NET Core 2.2 传递到 3.0 时,我忘记编辑/添加以使其工作时是否发生了变化,或者这是否已经可以工作?
Is there something that's changed when passing from ASP.NET Core 2.2 to 3.0 that I forgot to edit / add to make this work, or is this already supposed to work?
从 ASP.NET Core 2.2 传递到 3.0 时,我忘记编辑/添加以使其工作时是否发生了变化,或者这是否已经可以工作?
This is already supposed to work.这应该已经可以工作了。
Status.cshtml:状态.cshtml:
@page "{code?}"
@model StatusModel
@{
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@Model.PageTitle</title>
</head>
<body>
<div>
<h1>@Model.StatusNumber</h1>
<h2>@Model.StatusName</h2>
<h2>@Model.StatusDescription</h2>
</div>
</body>
</html>
Status.cshtml.cs:状态.cshtml.cs:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusModel : PageModel
{
public string PageTitle { get; set; }
public string StatusNumber { get; set; }
public string StatusName { get; set; }
public string StatusDescription { get; set; }
public void OnGet(string? code = null)
{
if (null == code)
code = HttpContext.Response.StatusCode.ToString();
PageTitle = $"HTTP status {code}";
StatusNumber = code;
if (code.CompareTo("404") == 0)
{
StatusName = "Not found";
StatusDescription = "The requested page was not found.";
}
else
{
StatusName = "Unknown error";
StatusDescription = "An unknown error occurred.";
}
}
}
Update:更新:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePagesWithReExecute("/Status/{0}");
app.UseExceptionHandler("/Status");
}
else
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePagesWithReExecute("/Status/{0}");
app.UseExceptionHandler("/Status");
// 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.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 401)
{
var newPath = new PathString("/Status/401");
var originalPath = context.Request.Path;
var originalQueryString = context.Request.QueryString;
context.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
{
OriginalPathBase = context.Request.PathBase.Value,
OriginalPath = originalPath.Value,
OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
});
// An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
// the endpoint and route values to ensure things are re-calculated.
context.SetEndpoint(endpoint: null);
var routeValuesFeature = context.Features.Get<IRouteValuesFeature>();
routeValuesFeature?.RouteValues?.Clear();
context.Request.Path = newPath;
try
{
await next();
}
finally
{
context.Request.QueryString = originalQueryString;
context.Request.Path = originalPath;
context.Features.Set<IStatusCodeReExecuteFeature>(null);
}
// which policy failed? need to inform consumer which requirement was not met
//await next();
}
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.