如何避免GetAwaiter()。GetResult 在重写的页面中

How can I avoid GetAwaiter().GetResult in an overridden page

提问人:djack109 提问时间:11/3/2023 更新时间:11/8/2023 访问量:50

问:

我正在使用 VS2022 和 Net7 网络应用程序。

我有这个页面,用于处理常见的东西,所以我不必把它放在每个页面中

public class ApplicationPageModel : PageModel
{        
    public IActionResult? OnGet()
    {
        //cookie handling
        //page set up
        //security checking
        //etc

        return null;
    }
}

然后我所有其他页面都看起来像这样

public class PermissionsModel : ApplicationPageModel
{
    public override async void OnPageHandlerExecuted(PageHandlerExecutedContext context)
    {
        if (context.HandlerMethod!.MethodInfo.Name == nameof(OnGet))
        {
            string page = HttpContext.Request.Query["id"].ToString();

            //page specific code goes here'
            //do something awaitable here
        }

        base.OnPageHandlerExecuted(context);

    }
}

我无法在实际页面中使用,因为我收到此错误OnGet

An unhandled exception occurred while processing the request. InvalidOperationException: Multiple handlers matched. The following handlers matched route data and had all constraints satisfied:

问题是使用,然后我必须使用.GetAwaiter() 中。GetResult(),因为 Razor 页面在我的可等待 API 调用完成之前呈现。因此,任何模型更新(null)都未完成,因此我在页面中出现null异常。例如,如果我使用:-OnPageHandlerExecuted

@foreach(var stuff in Model.Stuff)Model.Stuff 始终为 null,因为该方法在页面之后完成。

如果没有使用普通覆盖,一切都很好,但是我必须在每个页面中放置代码,并且我正在我的应用程序中计划很多页面。OnGet

我使用没有问题,但我被告知它要么不安全,要么不是一个好主意。否则我怎么能以安全的方式实现同样的目标。.GetAwaiter().GetResult()

有人有什么想法吗?

C# asp.net Razor

评论

3赞 Roe 11/3/2023
您是否尝试过使 OnGet 异步?然后通常等待
1赞 MakePeaceGreatAgain 11/3/2023
“然后我必须使用.GetAwaiter() 中。GetResult() 在我的异步方法上,因为 Razor 页面在我的可等待 API 调用完成之前呈现“ 哎呀,这就是我们实际上有的原因。然而,除了潜在的僵局之外,它不应该有什么不同。awaitGetResult()
1赞 MakePeaceGreatAgain 11/3/2023
似乎您实际上应该是一些或类似的,因为此函数不是请求处理程序,而只是一个“普通”实用程序方法。话虽如此,你应该更喜欢组合而不是继承,继承不是派生,而只是使用它(这也避免了首先派生这个类,从而进一步避免了与-router-函数的命名冲突)。OnGetBeforeGetApplicationPageModelPageModelGet

答:

1赞 MakePeaceGreatAgain 11/3/2023 #1

我认为你的实际问题不是关于或,而是关于一个非常不幸的类设计。您的基类似乎与 没有任何关系,但恰好具有这种继承,只是为了在所有页面上共享一些通用功能。最好使用组合而不是继承来完成。所以毕竟你的 -class 只是一个实用程序类。这也由您的 -method 表示,只是返回而不是有效的响应。因此,与其派生该实用程序类,不如使用它awaitGetAwaiterPageModelApplicationModelOnGetnull

class static ApplicationHelpers
{
    public static async Task DoSomething() { await something }
}
public class MyPage : PageModel
{
    // now you can easily implement OnGet here, no more naming-collisions
    public Task<IActionResult> OnGetAsync()
    {
        // do the commmon stuff
        await ApplicationHelpers.DoSomething();

        // do the page-specific stuff here
    }
}

由于(或无论你怎么称呼它)现在也提出了一些请求,你可以自由地提出它,从而首先避免这种烦人的事情。当然,您应该考虑以某种方式在您的 -file 中注入对这个帮助程序类的依赖关系,为简洁起见,我省略了这一点并创建了类。ApplicationHelpers.DoSomethingasyncGetAwaiterProgram.csstatic

如果由于某种原因无法更改继承,则至少可以重命名基类中的 -function,因为该方法并不是真正的请求处理程序。相反,它只是在请求完成时应该发生的一些常见逻辑。因此,只需像这样在每个请求处理程序中使用 kin 调用该函数:OnGet

class ApplicationPageModel : PageModel
{
    public async Task DoSomething() { await something }
}
public class MyPage : PageModel
{
    // now you can easily implement OnGet here, no more naming-collisions
    public Task<IActionResult> OnGetAsync()
    {
        // do the commmon stuff
        await base.DoSomething();

        // do the page-specific stuff here
    }
}

评论

0赞 djack109 11/3/2023
我可能会试一试。我正在尝试尽可能少地编写代码,因为我有大量页面将使用我最终使用的任何方法。哦,OnBeforeGet 不起作用,在不使用 I'll post / accept an answer in few days in the days after after the following following with the the return a null again the null is not use I will post/accept an answer in few days, thanks all.GetAwaiter...
0赞 MakePeaceGreatAgain 11/3/2023
@djack109你的-function从字面上返回(除非这是一些虚拟代码,而不是你的实际代码)。ApplicationModel.OnGetnull
0赞 djack109 11/3/2023
是的,虚拟代码。实际上,它返回重定向或不返回任何内容,具体取决于其所做的所有检查。因为如果 is 不重定向,我希望实际页面处理接下来发生的任何事情
0赞 MakePeaceGreatAgain 11/3/2023
@djack109我仍然没有看到继承的正当理由。当然,您可以从一个页面重定向到另一个页面,而无需任何继承关系。很难知道普通和特殊事物的含义。
0赞 djack109 11/3/2023
谢谢,没关系,你的回答给了我思考的食物。:)