Сопоставить свойство строки xml со свойствами C # - PullRequest
0 голосов
/ 07 декабря 2018

Мне нужно сопоставить свойство 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?

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Один из вариантов может заключаться в том, чтобы обернуть его корневым узлом и использовать сериализуемый класс.

Класс будет выглядеть следующим образом:

[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));
0 голосов
/ 07 декабря 2018

Вы можете сделать следующее.Учитывая ваш тип источника.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...