如何写一个异步的Policy处理程序,注入一个作用域服务。

问题描述 投票:0回答:1

我试图为一个ASP.NET Core 3.1网络应用程序编写一个自定义策略,使用一个自定义身份存储提供商。

我试着去理解ASP.NET Core中的策略被设计成从用户信息中获取用户信息。HttpContext 对象,当我在 MSDN文章:

一旦你持有对用户的引用,你可以随时从索赔中找到用户名,并对任何数据库或外部服务进行查询。

我开始写自己的策略(就像现在简单的角色需求)注入了 UserManager 到构造函数中。

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

    public RoleHandler(UserManager<AppUser> usermanager)
    {
        UserManager = usermanager;
    }
}

现在我有几个问题

INJECTING A SCOPED SERVICE IN A SINGLETON.

策略应该是在整个应用生命中持续存在的,所以这应该是一个Singleton。

services.AddSingleton<IAuthorizationHandler, RoleHandler>();

但在策略服务器中注入的UserManager是一个scoped服务,这是不允许的。解决方法很简单,把策略服务的配置从单人服务改成了范围服务

services.AddScoped<IAuthorizationHandler, RoleHandler>();

但我不知道这是否会引起任何问题。

编写一个动态策略处理程序。

这是我对 HandleRequirementAsync 方法。

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;
}

我用的是 Task.Result 但它阻止了线程。我不能用 await 因为这将使该方法返回一个 Task<Task> 而非 Task 而我却无法改变它。我如何解决这个问题?

c# asp.net-core asynchronous policy
1个回答
2
投票

不要返回 Task.CompletedTask.

当你把一个方法声明为 async,它 隐性 返回一个 Task 当初 await 是打。

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);
    }
}

Task.CompletedTask 一般用于当你需要实现一个 Task 同步返回方法,而你不是。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.