【问题标题】:Razor custom error page ignores it's OnGet handlerRazor 自定义错误页面忽略它的 OnGet 处理程序
【发布时间】:2019-09-16 09:54:03
【问题描述】:

有自定义错误页面:

public sealed class ErrorModel : PageModel
{
    public ErrorModel()
    {
       // app stops at breakpoint inside ctor
    }

    public IActionResult OnGet()
    {
        // app doesn't stop here, why?

        // this is for debugging purposes only
        return BadRequest();
    }
}

及其观点:

@page
@model ErrorModel

@if (Model != null)
{
    <p>
        The error page.
    </p>
}

页面以常规方式注册:

app.UseExceptionHandler("/Error");

当应用程序重定向到错误页面时,它会在页面构造函数和页面视图内的断点处停止,但会忽略 OnGet 内的代码。由于应用程序不调用我的OnGet,因此页面呈现时没有我在OnGet 中填写的任何有用数据。

所有断点都已启用 - 我正在调试实际代码。

知道发生了什么以及如何解决这个问题吗?

UPD

我已经减少了页面模型代码和视图。 当应用程序在此行停止时:

@if (Model != null)

调用栈是:

Portal.App.Views.dll!Portal.Pages.Pages_Error.ExecuteAsync() 第 4 行 C# Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAdapter.ExecuteAsync() 未知 Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(Microsoft.AspNetCore.Mvc.Razor.IRazorPage 页面,Microsoft.AspNetCore.Mvc.Rendering.ViewContext 上下文)未知 Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(Microsoft.AspNetCore.Mvc.Razor.IRazorPage 页面, Microsoft.AspNetCore.Mvc.Rendering.ViewContext 上下文, bool invokeViewStarts) 未知 Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext 上下文) 未知 Microsoft.AspNetCore.Mvc.ViewFeatures.dll!Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, string contentType, int? statusCode) 未知 Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageResultExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageContext pageContext, Microsoft.AspNetCore.Mvc.RazorPages.PageResult 结果) 未知 Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.PageResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) 未知

所以,应用程序执行PageResult。这个结果是从哪里来的?

UPD 2

这看起来像是身份验证问题。当用户通过身份验证时,一切都按预期工作。但是对于未经身份验证的用户,我的 OnGet 不会被调用。 ErrorModel 没有 Authorize 属性。身份验证对此有何影响?

我没有任何自定义身份验证配置,因此,我假设使用默认值:

    private void ConfigureMvcServices(IServiceCollection services)
    {
        services
            .AddMvc()
            // another services;
    }

错误页面位于 Pages 文件夹 - Pages/Error

另外,如果用户没有认证,页面需要认证,必须返回401,不是吗?

【问题讨论】:

  • 如果你能分享一个minimal reproducible example,那就太棒了。
  • @mjwills:怎么样?此页面内有值得注意的异国情调。只需将错误页面添加到剃须刀页面应用程序项目中。但我相信你不会重现这个问题。我试图了解,应用程序如何调用页面模型 ctor 和视图代码,但不调用 OnGet。
  • 您的目标是什么版本的 .NET Core?
  • @MindSwipe:它是 2.2 版本。
  • 您是否尝试将@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 添加到剃须刀页面?

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


【解决方案1】:

我想通了。陷阱是here

为生产配置自定义错误处理页面 环境,使用异常处理中间件。中间件:

  • 捕获并记录异常。
  • 在指定的页面或控制器的备用管道中重新执行请求。如果响应不重新执行请求 已经开始了。

“重新执行”的字面意思是,如果在 GET 处理程序中引发异常,中间件会调用错误页面的 OnGet。如果在 POST 处理程序中引发,中间件调用 OnPost 等:

public class ErrorModel : PageModel
{
    public ErrorModel()
    {
    }

    public void OnGet()
    {
        // This executes when exception was in OnGet
    }

    public void OnPost()
    {
        // This executes when exception was in OnPost
    }

    // ...
}

在我的例子中,在带有身份验证的页面上有一个 GET 请求,在未通过身份验证的页面上有一个 POST 请求,所以这就是行为上的差异。

【讨论】:

    【解决方案2】:

    您是否在网络配置中启用了自定义错误。像这样:

    <httpErrors errorMode="Custom" existingResponse="Replace">
      <clear />
      <error statusCode="500" path="/Error" responseMode="ExecuteURL" />
    </httpErrors>
    

    【讨论】:

      猜你喜欢
      • 2012-12-06
      • 2013-11-19
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      • 2021-07-23
      • 2011-04-17
      • 1970-01-01
      • 2018-12-07
      相关资源
      最近更新 更多