【问题标题】:Why do I get "Missing type map configuration or unsupported mapping" error in automapper?为什么我在自动映射器中出现“缺少类型映射配置或不支持的映射”错误?
【发布时间】:2016-10-17 20:00:13
【问题描述】:

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;

namespace TestAutomapper
{
  class Program
  {
    static void Main(string[] args)
    {

      var config = new MapperConfiguration(cfg => cfg.CreateMap<MyClassSource, MyClassDestination>());


      var mapper = config.CreateMapper();

      var source = new MyClassSource { DateTimeValue = null };

      var mapped = mapper.Map<MyClassSource, MyClassDestination>(source);
    }

  }

  public class MyClassSource
  {
    public object DateTimeValue { get; set; }
  }

  public class MyClassDestination
  {
    public DateTime? DateTimeValue { get; set; }
  }
}

错误是:

    AutoMapper.AutoMapperMappingException was unhandled
      HResult=-2146233088
      Message=Error mapping types.

    Mapping types:
    MyClassSource -> MyClassDestination
    TestAutomapper.MyClassSource -> TestAutomapper.MyClassDestination

    Type Map configuration:
    MyClassSource -> MyClassDestination
    TestAutomapper.MyClassSource -> TestAutomapper.MyClassDestination

    Property:
    DateTimeValue
      Source=Anonymously Hosted DynamicMethods Assembly
      StackTrace:
           at lambda_method(Closure , MyClassSource , MyClassDestination , ResolutionContext )
           at TestAutomapper.Program.Main(String[] args) in C:\Users\costa\documents\visual studio 2015\Projects\TestAutomapper\TestAutomapper\Program.cs:line 22
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: 
           HResult=-2146233088
           Message=Missing type map configuration or unsupported mapping.

    Mapping types:
    Object -> Nullable`1
    System.Object -> System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
           Source=Anonymously Hosted DynamicMethods Assembly
           StackTrace:
                at lambda_method(Closure , Object , Nullable`1 , ResolutionContext )
                at lambda_method(Closure , MyClassSource , MyClassDestination , ResolutionContext )
           InnerException: 

我认为这个错误已经解决了 (https://github.com/AutoMapper/AutoMapper/issues/1095)。我正在使用 Automapper 5.1.1。

我该如何解决这个问题?

谢谢

编辑:澄清一下,我关心的是空值的处理。我知道从非空对象值转换为 DateTime 很复杂。在实际代码中,源对象中的实际值为 null 或 DateTime。我认为 null 的处理没有错误。

编辑:

我创建了一个扩展方法 ToDate 来将对象转换为日期,并添加了这个映射来处理从对象到 DateTime 的转换?:

cfg.CreateMap<object, DateTime?>().ConstructUsing(src => src.ToDate());

【问题讨论】:

  • 自从我使用 AutoMapper 已经有一段时间了,但我相信需要在两种类型之间的映射(例如 objectDateTime?)才能自动将相同的属性名称映射到不同的类型.所以要么在objectDateTime? 之间添加一个映射(这看起来很恶心),要么使用自定义分辨率选项。

标签: c# automapper-5


【解决方案1】:

由于源类型和目标类型中的属性名称相同,AutoMapper 会尝试从对象转换为 DateTime?这是不可能的,这就是您收到您提到的错误的原因。

您需要定义如何解析 DateTime?财产。这将起作用:

var config = new MapperConfiguration(
    cfg =>
    {
        cfg.CreateMap<MyClassSource, MyClassDestination>()
            .ForMember(
                destination => destination.DateTimeValue,
                memberOptions => memberOptions.ResolveUsing(sourceMember =>
                {
                    DateTime dateTime;
                    return !DateTime.TryParse(sourceMember.DateTimeValue.ToString(), out dateTime) ? (DateTime?) null : dateTime;
                }));
    }
);

如果您的源成员是有效的日期时间对象,它将被转换为日期时间,否则目标属性将获得空值。

【讨论】:

  • 令人惊讶的是,null 是 DateTime 的有效值?多变的。以下代码:PropertyInfo pi = typeof(MyClassDestination).GetProperty("DateTimeValue"); MyClassDestination dst = new MyClassDestination(); pi.SetValue(dst, null); 工作正常。
  • 确实如此。但我认为关键是尽管 null 是 DateTime 的有效值?属性,你不能保证它总是为空,因为源属性是一个对象。因此,它也可能具有任何其他无效值,因此会出现错误。如果源属性的值为“Foo”(字符串)怎么办?
  • 我同意你的看法。但是,我认为 automapper 提供了一些默认的转换例程,这些例程至少可以处理空值(只要目标可以为空)或兼容类型的值。
  • @costa 您将源的 value 与源的 type 混淆了。虽然 Automapper 确实可以正确映射 null 值,但它不能一般将任何对象映射到 DateTime?,因此它失败了,因为在这两种类型之间没有定义映射。在相同可为空类型的两个属性之间进行映射时,您链接到的问题会失败,这是不同的。
  • @DStanley:我不认为我混淆了他们。我期望自动映射器在运行时提供某种默认转换。在这种特殊情况下,目标属性是 DateTime?源属性是对象。我希望 automapper 至少会执行以下代码(大致 - 在伪代码中):if (source value is null and destination property type is nullable) then return null; if (source value type is the same as the destination property type) then return original value; 等...
猜你喜欢
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2013-01-18
  • 2019-03-01
  • 2017-04-16
  • 2015-09-22
相关资源
最近更新 更多