如何根据用户权限使用 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();
}
我在我的应用程序中成功地使用了 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();
}