ASP.NET Core 2.1中AutoMapper实现DateTime与String互转的问题
解决AutoMapper中DateTime与String的双向映射问题
首先,咱们来拆解你遇到的问题根源:
- 错误的成员配置:你在
ForMember里写了dest => dest.SomeDate.ToString(_dateFormat),AutoMapper只允许映射到目标类的直接成员属性,不能是方法调用,这就是抛出AutoMapperConfigurationException的核心原因。 - 重复的成员映射:你对同一个
SomeDate成员重复配置了两次ForMember,这会导致配置冲突,甚至无提示终止运行。 - 方法类型错误:你的
Map方法返回类型写了User(应该是Customer),参数引用也写错了(customer应该是user)。
接下来是正确的实现方案,分两种场景给出:
基础版:直接在映射配置中完成转换
先修正你的ObjectsMapper类,确保映射配置合法且正确:
using System.Globalization; using AutoMapper; public class ObjectsMapper { private readonly IMapper _mapper; private const string _dateFormat = "yyyy-MM-dd'T'HH:mm"; // 修正格式字符串的多余转义 public ObjectsMapper() { var config = new MapperConfiguration(cfg => { // Customer(string日期)转CustomerTO(DateTime) cfg.CreateMap<Customer, CustomerTO>() .ForMember(dest => dest.SomeDate, opt => opt.MapFrom(src => DateTime.ParseExact(src.SomeDate, _dateFormat, CultureInfo.InvariantCulture))); // CustomerTO(DateTime)转Customer(string日期) cfg.CreateMap<CustomerTO, Customer>() .ForMember(dest => dest.SomeDate, opt => opt.MapFrom(src => src.SomeDate.ToString(_dateFormat, CultureInfo.InvariantCulture))); }); // 启动时验证配置,提前发现错误 config.AssertConfigurationIsValid(); _mapper = config.CreateMapper(); } // 修正方法的类型错误,补充双向映射方法 public Customer Map(CustomerTO customerTo) => _mapper.Map<Customer>(customerTo); public CustomerTO Map(Customer customer) => _mapper.Map<CustomerTO>(customer); }
关键修正点说明:
- 格式字符串优化:去掉多余单引号,使用标准ISO格式写法,搭配
CultureInfo.InvariantCulture避免系统区域差异影响转换结果。 - 合法的成员指向:
ForMember的第一个参数直接指向目标类的属性(比如dest => dest.SomeDate),而非方法调用。 - 配置验证:添加
config.AssertConfigurationIsValid(),在启动阶段就能检测配置错误,避免运行时莫名崩溃。 - 修正方法签名:确保返回类型和参数类型匹配,补充双向映射的方法。
进阶版:使用TypeConverter实现可复用的日期转换
如果项目中有多处需要这种日期格式转换,推荐用ITypeConverter封装转换逻辑,更易维护:
using System.Globalization; using AutoMapper; // DateTime转指定格式string的转换器 public class DateTimeToStringConverter : ITypeConverter<DateTime, string> { private readonly string _dateFormat; public DateTimeToStringConverter(string dateFormat) { _dateFormat = dateFormat; } public string Convert(DateTime source, string destination, ResolutionContext context) { return source.ToString(_dateFormat, CultureInfo.InvariantCulture); } } // string转DateTime的转换器 public class StringToDateTimeConverter : ITypeConverter<string, DateTime> { private readonly string _dateFormat; public StringToDateTimeConverter(string dateFormat) { _dateFormat = dateFormat; } public DateTime Convert(string source, DateTime destination, ResolutionContext context) { return DateTime.ParseExact(source, _dateFormat, CultureInfo.InvariantCulture); } }
然后在映射配置中使用这些转换器:
public ObjectsMapper() { const string dateFormat = "yyyy-MM-dd'T'HH:mm"; var config = new MapperConfiguration(cfg => { cfg.CreateMap<Customer, CustomerTO>() .ForMember(dest => dest.SomeDate, opt => opt.ConvertUsing(new StringToDateTimeConverter(dateFormat), src => src.SomeDate)); cfg.CreateMap<CustomerTO, Customer>() .ForMember(dest => dest.SomeDate, opt => opt.ConvertUsing(new DateTimeToStringConverter(dateFormat), src => src.SomeDate)); }); config.AssertConfigurationIsValid(); _mapper = config.CreateMapper(); }
这种方式的好处是转换逻辑可复用,后续修改日期格式只需调整转换器参数即可。
测试验证
可以写一段简单代码验证映射是否正常:
var mapper = new ObjectsMapper(); // 测试CustomerTO转Customer var customerTo = new CustomerTO { Id = 1, SomeDate = new DateTime(2024, 5, 20, 14, 30) }; var customer = mapper.Map(customerTo); Console.WriteLine(customer.SomeDate); // 输出:2024-05-20T14:30 // 测试Customer转CustomerTO var customer2 = new Customer { Id = 2, SomeDate = "2024-05-21T09:15" }; var customerTo2 = mapper.Map(customer2); Console.WriteLine(customerTo2.SomeDate); // 输出正确的DateTime值
内容的提问来源于stack exchange,提问作者Kgn-web
相关产品推荐
相关产品推荐

