如何根据用户权限使用 Automapper 有条件地映射属性

How can I conditionally map properties using Automapper based on user permissions

我在我的应用程序中成功地使用了 Automapper,但是我遇到了一个我找不到解决方案的特殊要求。

我的应用程序是一个使用 Automapper 10 的 ASP.Net Core 3.1 应用程序。如果用户有权编辑这些特定属性,我需要做的只是将某些属性从 Dto 映射到数据实体。我正在使用 Claims Principal 来存储我需要的关于用户的信息。

在最简单的形式中,如果执行编辑的用户是管理员,我只想映射 属性“已启用”。我可以根据声明检查用户是否是管理员,但我不知道如何让 Automapper 知道这一点。

在这种情况下可以完成还是我最好手动映射?

提前致谢

一种方法是在运行时将用户角色信息存储在 Items 字典中。然后使用 Condition() 您可以通过从同一个 Items 字典中检索用户角色信息来检查映射期间的角色。

控制器内部的映射用法:

var entity = mapper.Map<Entity>(dto, opts =>
{
    opts.Items["UserRole"] = User.FindFirst(ClaimTypes.Role)?.Value;
});

映射配置:

CreateMap<DTO, Entity>()
    .ForMember(
        d => d.Enabled,
        o =>
        {
            o.Condition((s, d, sm, dt, resolutionContext) =>
            {
                return resolutionContext.Items.TryGetValue("UserRole", out var userRole)
                    && userRole.ToString() == "Admin";
            });
            o.MapFrom(s => s.Enabled);
        });

其他方法是使用 ResolutionContext 中的选项中的 ServiceCtor 来解析建立用户角色所需的任何服务,我将以 IHttpContextAccessor 为例:

映射用法完全没有改变:

var entity = mapper.Map<Entity>(dto);

映射配置有点复杂:

CreateMap<DTO, Entity>()
    .ForMember(
        d => d.Enabled,
        o =>
        {
            o.Condition((s, d, sm, dt, resolutionContext) =>
            {
                var httpContextAccessor = resolutionContext
                    .Options
                    .ServiceCtor(typeof(IHttpContextAccessor)) as IHttpContextAccessor;
                var userRole = httpContextAccessor
                    .HttpContext
                    .User
                    .FindFirst(ClaimTypes.Role)
                    ?.Value;

                return userRole == "Admin";
            });
            o.MapFrom(s => s.Enabled);
        });

请记住 IHttpContextAccessor 并不总是 return 一个 HttpContext。可能是null。它还要求您在 Startup class:

中的 ConfigureServices() 中注册它
public void ConfigureServices(IServiceCollection services)
{
     services.AddHttpContextAccessor();
}