如何对具有多个XmlElementAttributes的对象使用自动映射器?

时间:2019-04-02 09:48:35

标签: c# xml xsd automapper

我无法为从.xsd .cs文件生成的对象设置自动映射器。

不确定当对象具有多个属性时如何解决该问题,如下所示:

曾经看过TypeConverters等,但不确定如何正确设置它。现在已经使用automapper一段时间了,只要没有多个属性连接到一个成员就没有问题。

public partial class customerInfo {

    private object itemField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("customerInfoBasic", typeof(customerInfoBasic))]
    [System.Xml.Serialization.XmlElementAttribute("customerInfoSimple", typeof(customerInfoSimple))]
    [System.Xml.Serialization.XmlElementAttribute("customerInfoEnhanced", typeof(customerInfoEnhanced))]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

public partial class customerInfoBasic{

    private string nameField;

    /// <remarks/>
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField= value;
        }
    }
}

public partial class customerInfoSimple{

    private string nameField;
    private string idField;


    /// <remarks/>
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField= value;
        }
    }

    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField= value;
        }
    }
}

public partial class customerInfoEnhanced{

    private string nameField;
    private string idField;
    private string ageField;

    /// <remarks/>
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField= value;
        }
    }

    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField= value;
        }
    }

    public string age {
        get {
            return this.ageField;
        }
        set {
            this.ageField= value;
        }
    }
}

我遇到的问题是,我不知道如何设置它,以便根据“ Info”中的某些值正确映射customerInfo。

例如,如果“信息”包含“年龄”和“ id”,则应将其映射到customerInfoEnhanced等。

public static void AddSessionTransformationMappings(IMapperConfiguration cfg)
{
    cfg.AllowNullCollections = true;

    cfg.CreateMap<IEnumerable<Info>, customerInfoList>()
        .ForMember(x => x.customerInfo, x => x.MapFrom(y => y));

    cfg.CreateMap<Info, customerInfo>()
        .ForMember(x => x.Item, x => x.MapFrom(y => y));

    cfg.CreateMap<Info, customerInfoBasic>()
        .ForMember(x => x.Name, x => x.MapFrom(y => y.name));

    cfg.CreateMap<Info, customerInfoSimple>()
        .ForMember(x => x.Name, x => x.MapFrom(y => y.name))
        .ForMember(x => x.Id, x => x.MapFrom(y => y.id));

    cfg.CreateMap<Info, customerInfoEnhanced>()
        .ForMember(x => x.Name, x => x.MapFrom(y => y))
        .ForMember(x => x.Id, x => x.MapFrom(y => y.id))
        .ForMember(x => x.Age, x => x.MapFrom(y => y.age));
}

这也是序列化器的代码:

var output = provider.Transform(new List<Info> { input });

customerInfoList actual = null;
XmlSerializer serializer = new XmlSerializer(typeof(customerInfoList));
using (MemoryStream ms = new MemoryStream())
{
    serializer.Serialize(ms, output);
    ms.Position = 0;
    actual = (customerInfoList)serializer.Deserialize(ms);
}

如果我设置了.ForMember(x => x.customerInfo, x => x.MapFrom(y => (Object)null)); 该代码可以正常工作,并且“实际”按预期提供给我一个列表,其中item = null,所以我知道问题出在customerInfo中映射“ Item”。

我希望映射器能够映射到正确的类,现在我会得到Missing类型映射或“未预期到信息。请使用XmlInclude或SoapInclude属性指定静态未知的类型。

非常感谢您提供一些有关如何解决该问题的建议!

1 个答案:

答案 0 :(得分:0)

为我自己的需要解决了问题,如果其他人遇到相同的问题,请在下面解决。

对我来说,解决方案是对具有多个标签名称的特定属性使用ResolveUsing而不是MapFrom,并针对不同情况使用具有正确类的Mapper.Map。

完整代码如下:

public static void AddSessionTransformationMappings(IMapperConfiguration cfg)
{
    cfg.AllowNullCollections = true;

    cfg.CreateMap<IEnumerable<Info>, customerInfoList>()
        .ForMember(x => x.customerInfo, x => x.MapFrom(y => y));

    cfg.CreateMap<Info, customerInfo>()
        .ForMember(x => x.Item, x => x.ResolveUsing(y => CustomerInfoLevel(y)));

    cfg.CreateMap<Info, customerInfoBasic>()
        .ForMember(x => x.Name, x => x.MapFrom(y => y.name));

    cfg.CreateMap<Info, customerInfoSimple>()
        .ForMember(x => x.Name, x => x.MapFrom(y => y.name))
        .ForMember(x => x.Id, x => x.MapFrom(y => y.id));

    cfg.CreateMap<Info, customerInfoEnhanced>()
        .ForMember(x => x.Name, x => x.MapFrom(y => y.name))
        .ForMember(x => x.Id, x => x.MapFrom(y => y.id))
        .ForMember(x => x.Age, x => x.MapFrom(y => y.age));
}

private static Object CustomerInfoLevel(Info info)
{
    if (info.age != null)
    {
        return Mapper.Map<customerInfoEnhanced>(info);
    }
    else if (info.id != null)
    {
        return Mapper.Map<customerInfoSimple>(info);
    }
    else
    {
        return Mapper.Map<customerInfoBasic>(info);
    }
}
相关问题