我正在使用;
AutoMapper.Extensions.Microsoft.DependencyInjection 6.0.0
在运行net core 2.2
的网络api项目中
映射我的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);
所有标准成员都映射到上面列出的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);
有人知道为什么会这样吗?
答案 0 :(得分:0)
您需要使用“ 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)));
});
}
}
}
答案 1 :(得分:0)
经过一番调查,我认为我已转载了您的问题。我创建了一个基本的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: 找到未映射的成员。在下面查看类型和成员。 添加自定义映射表达式,忽略,添加自定义解析器或修改> source / destination类型
对于没有匹配的构造函数,请添加一个无参数ctor,添加可选参数,或映射所有?构造函数参数
AutoMapper为您创建了此类型映射,但是无法使用当前配置来映射您的类型。 ReviewPostInputModel->评论(目标成员列表) ReviewPostInputModel->评论(目标成员列表)
未映射的属性: 平均分 接收更新 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);
如果这不是您的问题,那么无论是因为我花了很多时间在解决这个问题上,还是治愈了我的失眠症。