【问题标题】:handling exception in ASP .NET 3.1 core controller when using razor pages使用剃须刀页面时处理 ASP .NET 3.1 核心控制器中的异常
【发布时间】:2020-08-09 13:58:46
【问题描述】:

我有使用剃须刀页面的 ASP .NET Core 3.1 网站,但也有从 ASP .NET Core Controller 类继承的单个控制器。控制器处理有效负载,然后在成功时重定向到剃刀页面之一。我注意到当控制器中存在未处理的异常时,浏览器会显示 HTTP 400 - Bad Request 错误,但我希望控制器简单地使用我已经定义的异常处理程序,如下所示:

if (env.IsDevelopment())
   app.UseDeveloperExceptionPage();
else
   app.UseExceptionHandler("/Error");

在上面,“/Error”路径是剃须刀页面。在非开发模式下,控制器不使用我的异常处理程序,只显示 HTTP 400 - Bad Request browser 错误。

我设法让它与异常过滤器类一起使用,在 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();
    });
}

提前致谢!

【问题讨论】:

  • 您的 web.config 或 Startup.cs(或类似)文件中是否有任何内容可能会干扰您的代码?
  • 我找不到任何不寻常的地方。请参阅我的帖子中的启动代码。

标签: c# asp.net-core razor-pages


【解决方案1】:

我终于明白发生了什么。我的控制器正在处理 POST 方法。当发生任何未处理的异常时,代码将尝试运行我的异常处理程序。由于 POST,它会发布到我的异常处理程序页面,但由于 AntiForgery 请求验证令牌丢失而失败,因此它发出 HTTP 400 - Bad Request,我之前在使用 jQuery 和 AJAX if 令牌的页面中看到过失踪。所以基本上,为了解决这个问题,我将在我的 razor 错误页面处理程序中添加 [IgnoreAntiforgeryToken] 属性。

【讨论】:

    【解决方案2】:

    如果您想使用 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}");
        }
      }
    

    【讨论】:

    • 我的错误页面中已经有公共异步任务 OnGetAsync() 方法,但是当我的控制器发生未处理的异常时,不会重定向到错误页面。
    • 这里是:public async Task OnGetAsync() { await this.HttpContext.SignOutAsync();但实际上该方法并没有在未处理的异常中被触发。被解雇的是 OnPostAsync()。另外,我终于弄清楚了为什么会收到 HTTP 400 错误。看我的回答——这是由于防伪令牌。
    【解决方案3】:

    试试这个 app.UseExceptionHandler("/Home/Error"); 工作原因请检查您的 HomeController 应该有下面的默认操作方法 [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 公共 IActionResult 错误() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); }

    如果不存在,您可以在任何控制器中创建此方法并提供该控制器的路径,例如app.UseExceptionHandler("/YourController/Error");

    【讨论】:

    • 我已经有 Error razor 页面并且已经在使用 app.UseExceptionHandler("/Error")
    猜你喜欢
    • 2020-10-14
    • 2021-11-19
    • 2019-05-29
    • 2020-07-11
    • 2021-10-07
    • 2019-06-13
    • 2022-10-07
    • 2020-11-09
    • 1970-01-01
    相关资源
    最近更新 更多