C# 如何编写异步策略处理程序,注入作用域服务

C# 如何编写异步策略处理程序,注入作用域服务,c#,asp.net-core,asynchronous,C#,Asp.net Core,Asynchronous,我正在尝试使用自定义标识存储提供程序为ASP.NET Core 3.1 web应用程序编写自定义策略 当我在下面的一篇文章中读到这篇文章时,我试图让自己的头脑明白ASP.NET Core中的策略是为了从HttpContext对象获取用户信息而设计的: 一旦持有对用户的引用,您就可以从声明中找到用户名,并对任何数据库或外部服务运行查询 我现在开始编写自己的策略,一个简单的角色要求是将UserManager注入构造函数: public class RoleHandler : Authorizatio

我正在尝试使用自定义标识存储提供程序为ASP.NET Core 3.1 web应用程序编写自定义策略

当我在下面的一篇文章中读到这篇文章时,我试图让自己的头脑明白ASP.NET Core中的策略是为了从HttpContext对象获取用户信息而设计的:

一旦持有对用户的引用,您就可以从声明中找到用户名,并对任何数据库或外部服务运行查询

我现在开始编写自己的策略,一个简单的角色要求是将UserManager注入构造函数:

public class RoleHandler : AuthorizationHandler<RoleRequirement>
{
    private UserManager<AppUser> UserManager;

    public RoleHandler(UserManager<AppUser> usermanager)
    {
        UserManager = usermanager;
    }
}
我使用了Task.Result,但它阻塞了线程。我不能使用wait,因为这会使方法返回一个任务而不是一个任务,我不能更改它。如何解决此问题?

不要返回Task.CompletedTask

当您将一个方法声明为async时,它会在命中第一个等待时隐式返回一个任务:

Task.CompletedTask通常在需要同步实现任务返回方法时使用,但实际情况并非如此。

不要返回Task.CompletedTask

当您将一个方法声明为async时,它会在命中第一个等待时隐式返回一个任务:


Task.CompletedTask通常在需要同步实现任务返回方法时使用,而实际情况并非如此。

不要返回任务。已完成的任务只需像这样编写Wait Task.CompletedTask;为什么不像下面这样使用context.User.IsInRolerequirement.Role。ToString@MuhammadSami上下文。用户不公开IsInRole方法,这是一个完全不同的实体。不返回任务。已完成的任务只需这样编写wait Task.CompletedTask;为什么不像下面这样使用context.User.IsInRolerequirement.Role。ToString@Muhammad用户不公开IsInRole方法,这是一个完全不同的实体。
services.AddSingleton<IAuthorizationHandler, RoleHandler>();
services.AddScoped<IAuthorizationHandler, RoleHandler>();
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirement requirement)
{
    AppUser user = UserManager.FindByIdAsync(context.User.Identity.Name).Result;

    if (user != null)
    {
        bool result = UserManager.IsInRoleAsync(user, requirement.Role.ToString()).Result;
        if (result) context.Succeed(requirement);
    }

    return Task.CompletedTask;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirement requirement)
{
    AppUser user = await UserManager.FindByIdAsync(context.User.Identity.Name);

    if (user != null)
    {
        bool result = await UserManager.IsInRoleAsync(user, requirement.Role.ToString());
        if (result) context.Succeed(requirement);
    }
}