使用 razor 页面时在 ASP .NET 3.1 核心控制器中处理异常
handling exception in ASP .NET 3.1 core controller when using razor pages
我有 ASP 使用剃刀页面的 .NET Core 3.1 网站,但也有继承自 ASP .NET Core 控制器 class 的单个控制器。控制器处理负载,然后在成功时重定向到剃刀页面之一。我注意到当控制器中存在未处理的异常时,浏览器显示 HTTP 400 - Bad Request 错误,但我希望控制器简单地使用我已经定义的异常处理程序,如下所示:
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
上面的“/Error”路径是razor page。在非开发模式下,控制器不使用我的异常处理程序,只显示 HTTP 400 - Bad Request 浏览器错误。
我设法让它与异常过滤器一起工作 class 在 OnException() 方法中,我记录了错误并手动重定向到“/Error”页面。异常过滤器如下所示:
private class CustomExceptionFilter : IExceptionFilter
{
private readonly IWebHostEnvironment hostingEnvironment;
private readonly ILogger<CustomExceptionFilter> logger;
public CustomExceptionFilter(IWebHostEnvironment hostingEnvironment, ILogger<CustomExceptionFilter> logger)
{
this.hostingEnvironment = hostingEnvironment;
this.logger = logger;
}
public void OnException(ExceptionContext context)
{
if (this.hostingEnvironment.IsDevelopment())
{
return;
}
this.logger.LogError(context.Exception, string.Empty);
context.Result = new RedirectToPageResult("/Error");
}
然后,我在控制器本身上定义了 [TypeFilter(typeof(CustomExceptionFilter))]。一切似乎都在工作,但似乎有很多活动部件。这是唯一的方法吗?还是我遗漏了什么?
这是启动代码:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts(options => options.MaxAge(365).IncludeSubdomains());
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseXRobotsTag(options => options.NoIndex().NoFollow());
app.UseXfo(options => options.SameOrigin());
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseXContentTypeOptions();
app.UseNoCacheHttpHeaders();
app.UseRedirectValidation();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
提前致谢!
试试这个 app.UseExceptionHandler("/Home/Error");
工作原因请检查您的 HomeController 操作方法下方应该有默认值
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult 错误()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
如果不存在,您可以在任何控制器中创建此方法并提供该控制器的路径,例如app.UseExceptionHandler("/YourController/Error");
如果您想使用 app.UseExceptionHandler("/Error");
,那么您的 Razor 页面可能如下所示。
Error.cshtml
@page "/Error"
@model Pages.Error
@{
Layout = null;
}
<h1>An unexpected error occured. Status Code: @HttpContext.Response.StatusCode</h1>
Error.cshtml.cs
public class Error : PageModel
{
private readonly ILogger<Error> _logger;
public Error(ILogger<Error> logger)
{
_logger = logger;
}
public void OnGet()
{
var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
if(exceptionHandlerFeature?.Error != null)
_logger.LogError($"This is a message from logger: {exceptionHandlerFeature.Error.Message}");
}
}
我终于明白是怎么回事了。我的控制器正在处理 POST 方法。当发生任何未处理的异常时,代码将尝试 运行 我的异常处理程序。由于 POST,它会 post 到我的异常处理程序页面,但由于 AntiForgery 请求验证令牌丢失而失败,因此它发出 HTTP 400 - 错误请求,我之前在我的如果缺少令牌,则使用 jQuery 和 AJAX 的页面。所以基本上,为了解决这个问题,我将向我的 razor 错误页面处理程序添加 [IgnoreAntiforgeryToken] 属性。
我有 ASP 使用剃刀页面的 .NET Core 3.1 网站,但也有继承自 ASP .NET Core 控制器 class 的单个控制器。控制器处理负载,然后在成功时重定向到剃刀页面之一。我注意到当控制器中存在未处理的异常时,浏览器显示 HTTP 400 - Bad Request 错误,但我希望控制器简单地使用我已经定义的异常处理程序,如下所示:
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
上面的“/Error”路径是razor page。在非开发模式下,控制器不使用我的异常处理程序,只显示 HTTP 400 - Bad Request 浏览器错误。
我设法让它与异常过滤器一起工作 class 在 OnException() 方法中,我记录了错误并手动重定向到“/Error”页面。异常过滤器如下所示:
private class CustomExceptionFilter : IExceptionFilter
{
private readonly IWebHostEnvironment hostingEnvironment;
private readonly ILogger<CustomExceptionFilter> logger;
public CustomExceptionFilter(IWebHostEnvironment hostingEnvironment, ILogger<CustomExceptionFilter> logger)
{
this.hostingEnvironment = hostingEnvironment;
this.logger = logger;
}
public void OnException(ExceptionContext context)
{
if (this.hostingEnvironment.IsDevelopment())
{
return;
}
this.logger.LogError(context.Exception, string.Empty);
context.Result = new RedirectToPageResult("/Error");
}
然后,我在控制器本身上定义了 [TypeFilter(typeof(CustomExceptionFilter))]。一切似乎都在工作,但似乎有很多活动部件。这是唯一的方法吗?还是我遗漏了什么?
这是启动代码:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts(options => options.MaxAge(365).IncludeSubdomains());
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseXRobotsTag(options => options.NoIndex().NoFollow());
app.UseXfo(options => options.SameOrigin());
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseXContentTypeOptions();
app.UseNoCacheHttpHeaders();
app.UseRedirectValidation();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
提前致谢!
试试这个 app.UseExceptionHandler("/Home/Error"); 工作原因请检查您的 HomeController 操作方法下方应该有默认值 [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult 错误() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); }
如果不存在,您可以在任何控制器中创建此方法并提供该控制器的路径,例如app.UseExceptionHandler("/YourController/Error");
如果您想使用 app.UseExceptionHandler("/Error");
,那么您的 Razor 页面可能如下所示。
Error.cshtml
@page "/Error"
@model Pages.Error
@{
Layout = null;
}
<h1>An unexpected error occured. Status Code: @HttpContext.Response.StatusCode</h1>
Error.cshtml.cs
public class Error : PageModel
{
private readonly ILogger<Error> _logger;
public Error(ILogger<Error> logger)
{
_logger = logger;
}
public void OnGet()
{
var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
if(exceptionHandlerFeature?.Error != null)
_logger.LogError($"This is a message from logger: {exceptionHandlerFeature.Error.Message}");
}
}
我终于明白是怎么回事了。我的控制器正在处理 POST 方法。当发生任何未处理的异常时,代码将尝试 运行 我的异常处理程序。由于 POST,它会 post 到我的异常处理程序页面,但由于 AntiForgery 请求验证令牌丢失而失败,因此它发出 HTTP 400 - 错误请求,我之前在我的如果缺少令牌,则使用 jQuery 和 AJAX 的页面。所以基本上,为了解决这个问题,我将向我的 razor 错误页面处理程序添加 [IgnoreAntiforgeryToken] 属性。