【问题标题】:Map xml string property to C# properties将 xml 字符串属性映射到 C# 属性
【发布时间】:2018-12-07 01:14:47
【问题描述】:

我需要将一个 xml 属性映射到 c# 属性。

var src = new Source();
src.Id = 1;
src.Name = "Test";
src.Address = "<Country>MyCountry</Country><Prefecture>MyPrefecture</Prefecture><City>MyCity</City>";

class Source
{
public string ID{ get; set; }
public string Name{ get; set; }
public string Address{ get; set; }
}        

        Class Destination
        {
        public string ID{ get; set; }
        public string Name{ get; set; }
        public string Country { get; set;}
        public string Prefecture { get; set;}
        public string City { get; set;}
        }

是否可以通过AutoMapper来实现?

【问题讨论】:

  • 只需使用标准的 xml 阅读器,它会为您提供可用于获取值和填充数据结构的对象结构。

标签: c# xml automapper


【解决方案1】:

您可以执行以下操作。考虑您的来源类型。

var src = new Source();
src.ID = 1;
src.Name = "Test";
src.Address = "<Country>MyCountry</Country><Prefecture>MyPrefecture</Prefecture><City>MyCity</City>";

由于您的源类型 (src.Address) 没有根元素,让我们添加一个并将 xml 解析为 XDocument。

XDocument xdoc = new XDocument();
xdoc = XDocument.Parse($"<Root>{src.Address}</Root>");

现在在 Automapper 初始化期间,您需要映射字段。

Mapper.Initialize(cfg =>
           cfg.CreateMap<XElement, Destination>()
               .ForMember(dest => dest.Country, opt => opt.MapFrom(x=>x.Element(nameof(Destination.Country)).Value))
               .ForMember(dest => dest.City, opt => opt.MapFrom(x => x.Element(nameof(Destination.City)).Value))
               .ForMember(dest => dest.Prefecture, opt => opt.MapFrom(x => x.Element(nameof(Destination.Prefecture)).Value)));

现在您可以按以下方式解决它。

 Destination result = Mapper.Map<XElement, Destination>(xdoc.Root);

更新

您也可以为此目的使用 ConstructUsing,这会将 Xml 相关代码隐藏在您的其他代码之外。

var src = new Source();
src.ID = "1";
src.Name = "Test";
src.Address = "<Country>MyCountry</Country><Prefecture>MyPrefecture</Prefecture><City>MyCity</City>";

XDocument xdoc = new XDocument();
xdoc = XDocument.Parse($"<Root>{src.Address}</Root>");

Mapper.Initialize(cfg =>
                    cfg.CreateMap<Source, Destination>()
                    .ConstructUsing(x=>ConstructDestination(x))
                 );

其中 ConstructDestination 定义为

static Destination ConstructDestination(Source src)
{
   XDocument xdoc = new XDocument();
   xdoc = XDocument.Parse($"<Root>{src.Address}</Root>");

   return new Destination
   {
     Country = xdoc.Root.Element(nameof(Destination.Country)).Value,
     City = xdoc.Root.Element(nameof(Destination.City)).Value,
     Prefecture = xdoc.Root.Element(nameof(Destination.Prefecture)).Value,
   };

 }

您的客户端代码现在看起来干净多了。

Destination result = Mapper.Map<Source, Destination>(src);

【讨论】:

  • 它有效。谢谢。
  • @Vignesh 很高兴它有帮助。如果帮助您解决问题,请将其标记为答案。
  • 我不知道这是否已经改变,但我认为.ConstructUsing实际上应该是.ConvertUsing,否则映射器会在使用提供的函数进行构建后尝试复制字段.
【解决方案2】:

一种选择是用根节点包装它并使用可序列化的类。

这个类看起来像这样:

[Serializable]
public class Address
{
    public string Country { get; set; }
    public string Prefecture { get; set; }
    public string City { get; set; }
}

反序列化如下所示:

        string xml = "<Country>MyCountry</Country><Prefecture>MyPrefecture</Prefecture><City>MyCity</City>";
        string wrapped = $"<Address>{xml}</Address>";
        XmlSerializer serializer = new XmlSerializer(typeof(Address));
        Address addr = (Address)serializer.Deserialize(new StringReader(wrapped));

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2018-09-15
    • 1970-01-01
    • 2018-01-22
    • 2023-04-07
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多