我想在AutoMapper中使用IValueResolver来映射两个类,一个值将从HttpRequest上下文中获取,所以我想使用IValueResolver
CreateMap<Dto, ViewModel>().ForMember(x=>x.MemberID, opt=>opt.Mapfrom<SpecialResolver>())
而且解析器很简单
public string Resolve(ViewModel viewModel, Dto dto, string destMember, ResolutionContext context)
{
return "test";
}
在启动类内部,我这样:
services.AddAutoMapper(typeof(Startup));
但是每次我将它们映射为MemberID时都会抛出错误,提示已丢弃IServiceProvider。 那么如何使这些工作呢?我尝试在启动时注入此SpecialResolver,但也无法正常工作。顺便说一句,我使用的是.net core 3.0
答案 0 :(得分:4)
我坚信错误会潜入您的代码中,从而引发问题。在我这边,一切正常。根据您的问题和评论,我尝试将您的工作保密。肯定会有或多或少的差异,但是您应该能够掌握这个想法并将其自己付诸实践。
我从映射配置文件开始,在这里我为HttpContextValueResolver
类的MemberId
属性显式指定ViewModel
的用法:
public class MyMappingProfile : Profile
{
public MyMappingProfile()
{
CreateMap<Dto, ViewModel>()
.ForMember(x => x.MemberId, opt => opt.MapFrom<HttpContextValueResolver>());
}
}
然后是值解析器:
public class HttpContextValueResolver : IValueResolver<Dto, ViewModel, string>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextValueResolver(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string Resolve(Dto source, ViewModel destination, string destMember, ResolutionContext context)
{
// Obtain whatever you need from HTTP context.
// Warning! HTTP context may be null.
return _httpContextAccessor.HttpContext?.Request.Path;
}
}
为了在控制器外部访问HttpContext,我使用了专用的IHttpContextAccessor
服务。在docs中详细了解它。
它不是自动可用的,因此我需要在Startup
中将其与AutoMapper一起注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAutoMapper(typeof(Startup));
services.AddHttpContextAccessor();
}
请注意,在仅传递一种类型(启动)的情况下注册AutoMapper时,要求所有映射配置文件都必须与启动在同一程序集(项目)中。对于多个程序集中的映射配置文件,您需要使用AddAutoMapper()
方法的适当重载来指定这些程序集或类型。
最后是在示例控制器中的用法:
public class HomeController : Controller
{
private readonly IMapper mapper;
public HomeController(IMapper mapper)
{
this.mapper = mapper;
}
public IActionResult Index()
{
var source = new Dto
{
MemberID = "123",
};
var result = mapper.Map<ViewModel>(source);
return View();
}
}
这是我使用的dto和视图模型:
public class Dto
{
public string MemberID { get; set; }
}
public class ViewModel
{
public string MemberId { get; set; }
}