【问题标题】:Strange behavior of Automapper when property type is ignored忽略属性类型时 Automapper 的奇怪行为
【发布时间】:2023-04-09 02:20:01
【问题描述】:

看到how to ignore a property type with Automapper后,我在一个测试项目中尝试过。事实证明,特定类型的属性被正确忽略,但在调用AssertConfigurationIsValid() 时抛出异常,指定找到未映射的成员。我可以理解这个异常的原因,因为应该忽略的类型的成员没有被映射,但我想知道是否应该在我故意删除映射的上下文中抛出这个异常。

对于给定的代码:

class Type1
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
}

class Type2
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public TypeToIgnore Prop3 { get; set; }
}

class MappingProfile : Profile
{
    public MappingProfile()
    {
        ShouldMapProperty = p => p.PropertyType != typeof(TypeToIgnore);
        CreateMap<Type2, Type1>();
    }
}

//...

var config = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile()));
config.AssertConfigurationIsValid(); //this throws AutoMapperConfigurationException

Automapper在验证配置的有效性时忽略成员而不抛出异常不就是正确的行为吗,就像忽略属性本身的情况一样?

CreateMap<Type2, Type1>().ForMember(x => x.Prop3, y => y.Ignore());

【问题讨论】:

  • 它只会验证@ZorgoZ 指出的目的地尝试反转您的 CreateMap 类型,然后调用 ReverseMap:CreateMap&lt;Type1, Type2&gt;().ReverseMap(); 仍应允许从 Type2 映射到 Type1。
  • @mxmissile 感谢您的回复,从 ZorgoZ 给出的答案中可以看出,我认为 Automapper API 的工作方式与其不同。

标签: c# automapper


【解决方案1】:

AutoMapper 从源映射到目标。据我所知,默认情况下源中存在但目标类型中缺少的字段将被忽略。您必须明确处理的是源中缺少的字段,但存在于目标类型中。在您的情况下,TypeToIgnore 在源代码中。因此,通过忽略该类型,您在目标中没有 Prop3 的源对应项。

作为说明,这不会抛出异常:

ShouldMapProperty = p => p.PropertyType != typeof(TypeToIgnore);
CreateMap<Type1, Type2>();

这也不会:

public class TypeToIgnore { }

void Main()
{

    var config = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile()));
    config.AssertConfigurationIsValid(); // won't throw
}

class Type1
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public bool Prop3 { get; set; } // <- because bool is ignored, you could simply delete this row
}

class Type2
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
    public TypeToIgnore Prop3 { get; set; }
    public long Prop4 { get; set; }
    public double Prop5 { get; set; }
}

class MappingProfile : Profile
{
    public MappingProfile()
    {
        ShouldMapProperty = p => p.PropertyType != typeof(bool);
        CreateMap<Type2, Type1>();
    }
}

【讨论】:

  • 我明白你在说什么,我不怀疑,但我想从Type2 映射到Type1,并且只忽略TypeToIgnore 的属性。所以在这种情况下,AssertConfigurationIsValid() 会抛出,因为Prop3 不会有任何映射。我要问的是:它抛出是否正常,因为我真的想忽略那种类型?我想这个问题的答案是肯定的,AssertConfigurationIsValid() 抛出是正常的,因为它不适合您添加到答案中的情况。
  • @meJustAndrew 是的,这很正常。您忽略了源中的某些内容,但您没有处理目的地中的对应物。您必须告诉 AutoMapper 如何处理与源不匹配的目标属性。现在,您只是从源中省略了一个属性。试试吧:完全删除public TypeToIgnore Prop3。你会得到同样的例外。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
相关资源
最近更新 更多