我有一個 asp.net 核心 API,它從 DB 物體映射到 ViewModel。ViewModel 中的某些屬性應該只提供給具有管理員角色的用戶。不僅是房產的價值,還有房產本身。
給定資料庫中的客戶物體
{
public string Name { get; set; }
public int Priority { get; set; }
}
和視圖模型
{
public string Name { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Priority { get; set; }
}
當 Controller 序列化為 JSON 時,如果 Priority 有值,它將如下所示
{
"name": "Customer Name",
"priority": 1
}
像這樣,如果優先級為空
{
"name": "Customer Name"
}
在地圖中,我需要檢查屬性是否具有 JsonIgnore 屬性以及用戶是否處于管理員角色中。如果用戶不在管理員角色中并且設定了屬性,它應該映射為空。
有沒有辦法遍歷目標的所有屬性并檢查屬性?
uj5u.com熱心網友回復:
一個選項是使用IValueResolver<in TSource, in TDestination, TDestMember>介面:
public class CustomerViewModelPriorityResolver: IValueResolver<Customer, CustomerViewModel, int?>
{
// As an example, if you have something similar
private readonly UserRepository _userRepository;
public CustomerViewModelPriorityResolver(IServiceProvider serviceProvider)
{
// You can use DI to inject whatever service you need.
// If, say, you have a UserRepository and you want to query the database
_userRepository = serviceProvider.GetService<UserRepository>();
}
public int? Resolve(Customer source, CustomerViewModel destination, int destMember, ResolutionContext context)
{
// determines whether the property has the [JsonIgnore] attribute
bool isJsonIgnore = typeof(CustomerViewModel ).GetProperty("Priority").GetCustomAttribute<JsonIgnoreAttribute>() is not null;
// If you want to query the database to get the user and his role (something similar)
var user = _userRepository.GetByName(source.Name);
var isAdmin = ...
// Continue with whatever logic you have
return // the value of 'Priority'; NULL or source.Priority;
}
}
在映射組態檔中:
public class MapperProfile : Profile
{
public MapperProfile()
{
CreateMap<Customer, CustomerViewModel>()
.ForMember(customerVM => customerVM.Priority, opt => opt.MapFrom<CustomerViewModelPriorityResolver>());
}
}
編輯
由于您想對許多屬性執行相同的操作,因此還有另一種選擇。IMappingAction<在 TSource 中,在 Tdestination 中>
public class CustomerViewModelAction : IMappingAction<Customer, CustomerViewModel>
{
private readonly UserRepository _userRepository;
public CustomerViewModelAction (IServiceProvider serviceProvider)
{
// DI
_userRepository = serviceProvider.GetService<UserRepository>();
}
public void Process(Customer source, CustomerViewModel destination, ResolutionContext context)
{
// Using DI, perform your querying logic to determine the role
var isAdmin = ...
if(isAdmin) {
// I don't know what you want to do if the user IS admin, but I'm assuming you just want to continue with the normal mapping
return;
}
var ignoredProperties = typeof(CustomerViewModel).GetProperties().Where(pi => pi.GetCustomAttribute<JsonIgnoreAttribute>() is not null);
foreach(var pi in ignoredProperties)
pi.SetValue(destination, null);
}
}
和映射組態檔:
public class MapperProfile : Profile
{
public MapperProfile()
{
CreateMap<Customer, CustomerViewModel>()
.AfterMap<CustomerViewModelAction>();
}
}
小費:
避免在映射中進行資料庫呼叫。假設您要映射List<Customer>
到List<CustomerViewModel>
. 您最終將得到 N 個資料庫呼叫。
Customer: bool IsAdmin
當您獲取有關客戶的資料時,您可以改為添加一個屬性并預先填充它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/528143.html