[英]UseStatusCodePagesWithReExecute shows blank page
我一直在尝试使用UseStatusCodePagesWithReExecute
方法来显示一个页面,该页面根据我尝试使用 ASP.NET Core 3.0 创建的应用程序上的状态代码显示自定义消息
我已按照此网站上的说明进行操作,但是现在,如果我尝试通过访问一个不存在的网页来对此进行测试,则会显示一个空白页面,并且代码不会通过 Razor 页面上的OnGet
方法我想要显示(我使用了断点)。
但是,我可以通过使用/Status/404
URI 手动访问浏览器上的页面来显示状态页面。
在启动文件中,我添加了所需的行,如教程中所示。
// Startup.cs
public static void Configure(IApplicationBuilder app,
IWebHostEnvironment env,
IHostApplicationLifetime appLifetime)
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePagesWithReExecute("/Status/{0}");
app.UseExceptionHandler("/Status");
// Irrelevant code below
}
状态模型包含一个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.";
}
}
}
状态视图非常简单:
@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>
在输出控制台上,我可以看到应用程序确实注意到它捕获了 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'
从 ASP.NET Core 2.2 传递到 3.0 时,我忘记编辑/添加以使其工作时是否发生了变化,或者这是否已经可以工作?
从 ASP.NET Core 2.2 传递到 3.0 时,我忘记编辑/添加以使其工作时是否发生了变化,或者这是否已经可以工作?
这应该已经可以工作了。
状态.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>
状态.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.";
}
}
}
更新:
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.