如何告诉Automapper尝试在源成员上调用.Value属性,而不是在UglySoapXml对象上调用.ToString()?

问题描述 投票:0回答:1

考虑这个课程:

public class UglyXmlSoapObject {
      public FIRST_NAMETYPESHAPE FIRST_NAMETYPESHAPE { get; set; }

      public LAST_NAMETYPESHAPE LAST_NAMETYPESHAPE { get; set; }

      public DEPT_TAX_CALCTYPESHAPE DEPT_TAX_CALCTYPESHAPE { get; set; }
}

public class FIRST_NAMETYPESHAPE {
      public String Value { get; set; }
}

public class LAST_NAMETYPESHAPE {
      public String Value { get; set; }
}

public class DEPT_TAX_CALCTYPESHAPE {
      public Decimal Value { get; set; }
}

XXXX_XXXXXXTYPESHAPE只是公开String属性(Value)的包装器/持有者类。因此,要实际获取firstName,请调用:

String firstName = uglyXmlObject.FIRST_NAMETYPESHAPE.Value;

如何告诉Automapper始终尝试映射给定对象的.Value属性?我有几十个我想映射的Xml类,如下所示:

UglyXmlSource.FIRST_NAMETYPESHAPE.Value => poco.FirstName UglyXmlSource.LAST_NAMETYPESHAPE.Value => poco.LastName

我已经发现我需要一个自定义命名约定,但是,为了获得源成员Value,Automapper只调用ToString(),所以poco.FirstName的值最终为:“AutoMapperDemo.Program + FIRST_NAMETYPESHAPE”

也许IValueResolver可以做到这一点?我尝试使用ResolveUsing指定ValueResolver / IMemberValueResolver,但是不明白该怎么做。

我希望ValueResolver可以处理任何通用对象; UglyXmlSoapObject的成员只是通用对象,但成员始终具有Value属性。

 public class SoapXmlNaming : INamingConvention
        {

            static CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;

            static TextInfo textInfo = cultureInfo.TextInfo;

            public string SeparatorCharacter
            {
                get { return "_"; }
            }

            public Regex SplittingExpression { get; } = new Regex(@"[\p{Ll}\p{Lu}0-9]+(?=_?)");

            public string ReplaceValue(Match match) =>
                textInfo.ToTitleCase(match.Value);


        }

  public class Poco
        {
            public String FirstName { get; set; }
            public String LastName { get; set; }
            public Decimal DeptTaxCalc { get; set; }
        }
c# automapper
1个回答
0
投票

我想出了答案。解决方案是使用自定义格式化程序来提取值,方法是注册使用ConvertUsing方法注册的Custom formatter(ITypeConvert的实现),如下所示:

public void Map(){
    var config = new MapperConfiguration(cfg =>
    cfg.CreateMap<Object, Object>().ConvertUsing<XmlPropertyConvert>();
    cfg.CreateMap<UglyXmlSoapObject, Poco>();
}

public class XmlPropertyConverter : ITypeConverter<Object,Object>{

public object Convert(object source, object destination, ResolutionContext context) {
    return GetValueObject(source)
}


private Object GetValueObject(Object member){
    var type = member.GetType();

    if (type.Name.ToLower().EndsWith("typeshape")){

    var property = type.GetProperties().SingleOrDefault(x => x.Name == "Value");
        if (property != null){
            var value = property.GetValue(member);
            return value;
        }

    }

    return member;

}

}
© www.soinside.com 2019 - 2024. All rights reserved.