我用的;
AutoMapper.Extensions.Microsoft.DependencyInjection 6.0.0
在一个web api项目中运行net core 2.2
在映射我的DTO对象时,我使用Automapper来映射几个字段;
public class AutoMapperProfile : AutoMapper.Profile
{
public AutoMapperProfile()
{
CreateMap<ReviewPostInputModel, Review>()
.ForMember(x => x.ReceiveThirdPartyUpdates, opt => opt.MapFrom(src => src.ReceiveThirdPartyUpdates ? (DateTime?)DateTime.UtcNow : null))
.ForMember(x => x.ReceiveUpdates, opt => opt.MapFrom(src => src.ReceiveUpdates ? (DateTime?)DateTime.UtcNow : null))
.ForMember(x => x.AverageScore, opt => opt.MapFrom(src => (decimal)Math.Round((src.Courtsey + src.Reliability + src.Tidiness + src.Workmanship) / 4, 2)));
// ...
}
}
哪里;
using System;
using System.Collections.Generic;
using System.Text;
public class Review
{
// ...
public decimal Reliability { get; set; }
public decimal Tidiness { get; set; }
public decimal Courtsey { get; set; }
public decimal Workmanship { get; set; }
public decimal AverageScore { get; set; }
public DateTime? ReceiveUpdates { get; set; }
public DateTime? ReceiveThirdPartyUpdates { get; set; }
}
但是,当我尝试使用地图时;
var review = _mapper.Map<Review>(model);
所有标准成员都映射到上面列出的my ForMember
,其中DateTimes设置为DateTime
的新实例,Averagescore设置为0。
为了完整性,我将映射器放入我的控制器中,如下所示;
private readonly IMapper _mapper;
public ReviewController( IMapper mapper)
{
_mapper = mapper;
}
我在StartUp.cs
中配置Automapper如下;
services.AddAutoMapper();
我还尝试向控制器添加一个测试,以确认输入的值不是问题(在映射之后完成并且可以确认该值已正确更新);
review.AverageScore = (decimal)Math.Round((model.Courtsey + model.Reliability + model.Tidiness + model.Workmanship) / 4, 2);
有没有人有任何想法为什么会这样?
你需要使用“ResolveUsing”而不是“MapFrom”
public class AutoMapperProfile : AutoMapper.Profile
{
public AutoMapperProfile()
{
CreateMap<ReviewPostInputModel, Review>()
.ForMember(x => x.ReceiveThirdPartyUpdates, opt => opt.ResolveUsing(src => src.ReceiveThirdPartyUpdates ? (DateTime?)DateTime.UtcNow : null))
.ForMember(x => x.ReceiveUpdates, opt => opt.ResolveUsing(src => src.ReceiveUpdates ? (DateTime?)DateTime.UtcNow : null))
.ForMember(x => x.AverageScore, opt => opt.ResolveUsing(src => (decimal)Math.Round((src.Courtsey + src.Reliability + src.Tidiness + src.Workmanship) / 4, 2)));
// ...
}
}
你可以看看这个答案:AutoMapper: What is the difference between MapFrom and ResolveUsing?
我们在过去从“ConfigureServices”添加自动映射器时遇到了问题,可能对您来说也是一样的。你可以尝试这个:
AutoMapperConfiguration.Init();
在启动功能中添加此类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
namespace yournamespace.ViewModels.Mappings
{
public static class AutoMapperConfiguration
{
public static void Init()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ReviewPostInputModel, Review>()
.ForMember(x => x.ReceiveThirdPartyUpdates, opt => opt.MapFrom(src => src.ReceiveThirdPartyUpdates ? (DateTime?)DateTime.UtcNow : null))
.ForMember(x => x.ReceiveUpdates, opt => opt.MapFrom(src => src.ReceiveUpdates ? (DateTime?)DateTime.UtcNow : null))
.ForMember(x => x.AverageScore, opt => opt.MapFrom(src => (decimal)Math.Round((src.Courtsey + src.Reliability + src.Tidiness + src.Workmanship) / 4, 2)));
});
}
}
}
经过一番调查,我想我已经复制了你的问题。我创建了一个基本的ASP.NET Core 2.2网站,安装了AutoMapper.Extensions.Microsoft.DependencyInjection 6.0.0
,创建了一个与你匹配的Review
类,并根据你的映射定义最好地猜测了ReviewPostInputModel
类的外观。然后我将您的映射配置文件类AutoMapperProfile
添加到项目中,并配置启动如下:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAutoMapper();
services.AddMvc...
}
然后我“破解”默认生成的HomeController,如此测试映射:
public class HomeController : Controller
{
private IMapper _mapper;
public HomeController(IMapper mapper)
{
_mapper = mapper;
}
public IActionResult Index()
{
var input = new ReviewPostInputModel();
input.ReceiveThirdPartyUpdates = true;
input.Tidiness = 3;
input.Reliability = 2;
input.NotDefinedOnProfile = "sss";
var output = _mapper.Map<Review>(input);
// Lazy test to avoid changing model.
throw new Exception($"{output.ReceiveThirdPartyUpdates} - {output.AverageScore} - {output.NotDefinedOnProfile}");
return View();
}
...
现在这对我有用,就像我收到的例外消息是11/04/2019 2:56:31 PM - 1.25 - sss
。
然后我创建了另一个程序集并将AutoMapperProfile
类移入其中。然后我重新运行测试,但得到以下错误:
AutoMapper.AutoMapperConfigurationException:找到未映射的成员。查看下面的类型和成员。添加自定义映射表达式,忽略,添加自定义解析程序或修改>源/目标类型
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of ?the constructor parameters
AutoMapper为您创建了此类型映射,但无法使用>当前配置映射您的类型。 ReviewPostInputModel - > Review(目标成员列表)ReviewPostInputModel - > Review(目标成员列表)
未映射的属性:AverageScore ReceiveUpdates NotDefinedOnProfile
这是有道理的,因为services.AddAutoMapper();
方法只搜索当前程序集中的profiles。
所以我然后改为配置为:services.AddAutoMapper(cfg => cfg.ValidateInlineMaps = false);
关闭错误,并重新运行测试。
新产出:1/01/0001 12:00:00 AM - 0 - sss
所以这让我相信AutoMapper找不到你的Profile类,在这种情况下,你可以使用以下方法手动配置它:
services.AddAutoMapper(cfg =>
{
cfg.AddProfile<AutoMapperProfile>();
});
或者手动定义要使用其他重载之一进行搜索的程序集,例如:
services.AddAutoMapper(param System.Reflection.Assembly[] assemblies);
如果这不是你的问题,不管是因为我花在复制这个问题上的时间已经治好了我的失眠。