You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在重写的Razor页面中避免使用GetAwaiter().GetResult()

解决方案

问题根源

  1. 基类ApplicationPageModel中的OnGet是具体实现,子类定义同名方法会导致ASP.NET Core路由匹配到多个处理程序,触发InvalidOperationException。
  2. OnPageHandlerExecuted是处理程序执行后的生命周期钩子,此时页面渲染流程已启动,异步操作无法及时更新模型,引发空引用异常;阻塞调用.GetAwaiter().GetResult()会导致线程死锁等风险。

方案一:重构基类为异步虚方法

将基类的通用逻辑封装到异步虚方法中,遵循ASP.NET Core命名约定(后缀Async),子类重写时先执行基类逻辑,再处理页面特定异步操作:

基类代码

public class ApplicationPageModel : PageModel
{        
    public virtual async Task<IActionResult?> OnGetAsync()
    {
        // cookie handling
        // page set up
        // security checking
        // etc

        return null; // 返回null表示继续执行子类逻辑
    }
}

子类代码

public class PermissionsModel : ApplicationPageModel
{
    public override async Task<IActionResult?> OnGetAsync()
    {
        // 先执行基类通用逻辑,若基类返回非空结果(如跳转)则直接返回
        var baseResult = await base.OnGetAsync();
        if (baseResult != null)
        {
            return baseResult;
        }

        string page = HttpContext.Request.Query["id"].ToString();

        // 执行页面特定异步逻辑(此时操作在页面渲染前完成)
        // Model.Stuff = await GetPagePermissionsAsync(page);

        return Page();
    }
}

方案二:使用页面过滤器分离通用逻辑

如果不想依赖基类继承,可通过异步页面过滤器实现通用逻辑复用,完全解耦页面特定代码:

实现页面过滤器

public class ApplicationPageFilter : IAsyncPageFilter
{
    public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
    {
        // 处理程序选择阶段:执行安全检查、Cookie验证等前置逻辑
        var httpContext = context.HttpContext;
        // cookie handling
        // security checking
    }

    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {
        // 处理程序执行前:完成页面配置等通用设置
        // page set up

        // 执行页面处理程序(如OnGetAsync)
        await next();

        // (可选)处理程序执行后的逻辑
    }
}

注册过滤器

在Program.cs中全局注册过滤器:

builder.Services.AddRazorPages(options =>
{
    options.Filters.Add<ApplicationPageFilter>();
});

子类简化代码

此时子类无需继承自定义基类,直接编写页面特定异步逻辑:

public class PermissionsModel : PageModel
{
    public async Task<IActionResult> OnGetAsync()
    {
        string page = HttpContext.Request.Query["id"].ToString();

        // 执行异步操作,模型更新在渲染前完成
        // Model.Stuff = await GetPagePermissionsAsync(page);

        return Page();
    }
}

内容的提问来源于stack exchange,提问作者djack109

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:32:56