如何对具有多个 XmlElementAttributes 的对象使用自动映射器?
How do I use automapper for objects with multiple XmlElementAttributes?
我在为 .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。
例如,如果 "Info" 包含 "age" 和 "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));
代码有效,"actual" 按预期给了我一个 item = null 的列表,所以我知道问题出在 customerInfo 中的映射 "Item"。
我希望映射器映射到正确的 class,现在我得到缺少类型映射或“信息不是预期的。使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。
非常感谢有关如何解决问题的一些指示!
根据我自己的需要解决了,如果其他人遇到同样的问题,请在下面解决。
我的解决方案是对具有多个标签名称的特定属性使用 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);
}
}
我在为 .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。
例如,如果 "Info" 包含 "age" 和 "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));
代码有效,"actual" 按预期给了我一个 item = null 的列表,所以我知道问题出在 customerInfo 中的映射 "Item"。
我希望映射器映射到正确的 class,现在我得到缺少类型映射或“信息不是预期的。使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。
非常感谢有关如何解决问题的一些指示!
根据我自己的需要解决了,如果其他人遇到同样的问题,请在下面解决。
我的解决方案是对具有多个标签名称的特定属性使用 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);
}
}