提问人:djack109 提问时间:11/3/2023 更新时间:11/8/2023 访问量:50
如何避免GetAwaiter()。GetResult 在重写的页面中
How can I avoid GetAwaiter().GetResult in an overridden page
问:
我正在使用 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()
有人有什么想法吗?
答:
我认为你的实际问题不是关于或,而是关于一个非常不幸的类设计。您的基类似乎与 没有任何关系,但恰好具有这种继承,只是为了在所有页面上共享一些通用功能。最好使用组合而不是继承来完成。所以毕竟你的 -class 只是一个实用程序类。这也由您的 -method 表示,只是返回而不是有效的响应。因此,与其派生该实用程序类,不如使用它:await
GetAwaiter
PageModel
ApplicationModel
OnGet
null
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.DoSomething
async
GetAwaiter
Program.cs
static
如果由于某种原因无法更改继承,则至少可以重命名基类中的 -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
}
}
评论
.GetAwaiter...
ApplicationModel.OnGet
null
评论
await
GetResult()
OnGet
BeforeGet
ApplicationPageModel
PageModel
Get