xml-serializasiya-praktikada---merkezi-bank-servisini-hazirlayiriq

XML Serializasiya praktikada : Mərkəzi bank servisini hazırlayırıq

Məqaləmizin ikinci hissəsində XML serializasiya ilə tanış olacaq və real praktikada Mərkəzi bankın xml servisinın istifadəsinə baxacağıq. Məqalənin 1-ci hissəsində serializasiya və deserializasiya nədir, həmçinin Binar serializasiya ilə tanış ola bilərsiniz.

               XML serializasiya vaxtı klasın mütləq şəkildə boş konstruktoru olmalı və klas serializasiya olunacaq üzvləri public əlçatma modifikatoru ilə göstərilməlidir.

               XML serializasiya zamanı XMLSerializer klasından istifadə olunur. Bu klas System.Xml.Serialization adsahəsində yerləşir. XmlSerializer klası konstruktordan hansı obyekti serializasiya edəcəksə həmin obyektin klasını tip olaraq arqument kimi qəbul edir. Misal: Əgər Person klasını serializasiya edəcəyiksə ozaman belə yazmalıyıq:

 [Serializable]
    public class User
    {
        [XmlElement(AttributeName = "Identifier")]
        public int Id { get; set; }
        [XmlElement(ElementName = "User_Name")]
        public string UserName { get; set; }

        [XmlElement]
        public string Email { get; set; }
        [XmlElement(ElementName = "Parol")]
        public string Password { get; set; }


        public bool IsLocked { get; set; }

        public override string ToString()
        {
            return $"{Id} {UserName} {Password} {IsLocked}";
        }
    }

               Serializasiya vaxtı klasın public property-ləri default olaraq xml elementlərə çevrilirlər. Əgər klasın property-ləri üzərində heçbir atribut göstərməsək default olaraq [XmlElement] atributu verilmiş sayılır. Əgər klasın property-ləri ilə xml-in elementlərinin adları arasında fərq qoymaq istəsək ozaman hər bir fərqlənməli olan property-nin üzərinə sadəcə XmlElement atributunu yazmaq və AttributeName vasitəsilə property-ni adlandırmaq lazımdır.

//klasin obyekti yaradilir
            User user = new User
            {
                Email = "midoriya@gmail.com",
                Id = 1,
                IsLocked = false,
                Password = "23423rd@#$s",
                UserName = "Midoriya"
            };

            //obyekt serializasiya olunur...
            XmlSerializer serializer = new XmlSerializer(typeof(User));
            using(FileStream fs = new FileStream("demo.xml",FileMode.OpenOrCreate))
            {
                serializer.Serialize(fs, user);
            }

Netice ise bele olacaq:

"1.0"?>
<User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Identifier>1Identifier>
  <User_Name>MidoriyaUser_Name>
  <Email>midoriya@gmail.comEmail>
  <Parol>23423rd@#$sParol>
  <IsLocked>falseIsLocked>
User>

               Əgər verilmiş klasdakı hər hansı bir property-nin nəticəsinin Xml atributa çevrilməsini istəyiriksə ozaman XmlAttribute adlanan atributdan istifadə etməliyik.

 public class User
    {
        [XmlAttribute(AttributeName = "Identifier")]
        public int Id { get; set; }
 ..........
}

Serializasiya kodu burada

Nəticə isə belə olacaq:

 "1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" Identifier="3" Age="45">
  <Name>TodorokiName>
  <Email>todoroki@gmail.comEmail>
Person>

 

XmlSerializasiyanı real praktikada tətbiq etmək üçün mərkəzi bankın verdiyi real servisi istifadə edəcəyik. (github adresimizda CbarService proyekti) Bu servis vasitəsilə verilmiş tarixə olan valyuta məlumatlarını əldə etmək olur. Misal: Əgər 06.09.2019-cu il üçün valyuta məlumatlarını əldə etmək istəsək ozaman https://www.cbar.az/currencies/06.09.2019.xml adresini istifadə etməliyik. Bizim yazacağımız proqramda tarix verildikdən sonra həmin tarixə uyğun məlumatlar ekranda əks olunacaq.

               Xml Serializasiya yerinə yetirlmək üçün ilk öncə verilən url adresə daxil olub xml strukturu haqqında məlumat alırıq. Aşağıdakı şəkildə həmin servisdən kiçik bir fragment göstərilib.

 Bizə url-dən gələn xml ilə bizim modelləşdirəcəyimiz klas ierarxiyası birbaşa bağlıdır. Ona görə klasları modelləşdirən zaman çox diqqətli olmaq lazımdır.

 Url-ə baxdıqdan sonra belə bir klas strukturu düzəldirik.

 [Serializable]
   public class Valute
    {
        [XmlAttribute]
        public string Code { get; set; }
        public string Nominal { get; set; }
        public string Name { get; set; }
        public decimal Value { get; set; }
        public override string ToString()
        {
            return $"{Name}   --   {Value} ";
        }
    }


 [Serializable]
   public class ValuteType
    {
        [XmlAttribute]
        public string Type { get; set; }

        [XmlElement(ElementName ="Valute")]
        public Valute[] Valutes { get; set; }
    }



 [Serializable]
    [XmlRoot(ElementName ="ValCurs")]
   public class ValuteCur
    {
        [XmlAttribute]
        public string Date { get; set; }
        [XmlAttribute]
        public string Name { get; set; }
        [XmlAttribute]
        public string Description { get; set; }

        [XmlElement(ElementName ="ValType")]
        public ValuteType[] ValTypes { get; set; }

    }




Xml Strukturunun baş elementi bizdə ValuteCur klası olduğuna görə onu XmlRoot atributu ilə işarələyirik. Bu atribut ilə həmçinin bir klasın serializasiya vaxtı adını dəyişə bilirik.

Servisin url adresini dinamik şəkildə qurmaq üçün spesifik klas ayırırıq. (Siz url-I birbaşa da daxil edə bilərsiniz, belə bir kod yazmaq məcburiyyətində deyilsiniz)

 public class ServiceUrlBuilder
    {
        private StringBuilder _url;
        public ServiceUrlBuilder()
        {
            _url = new StringBuilder();
        }
        public ServiceUrlBuilder AddBaseUrl(string baseUrl)
        {
            _url.Append(baseUrl);
            return this;
        }

        public ServiceUrlBuilder AddUrlSegment(string formatted)
        {
           string path = Path.Combine(_url.ToString(), formatted);
            _url.Clear();
            _url.Append(path);
            return this;
        }

        public ServiceUrlBuilder AddServiceExtension(string extension)
        {
            _url.Append($".{extension}");
            return this;
        }
        public string Build()
        {
            return _url.ToString();
        }
    }

ServiceUrlBuilder klasımız imkan verəcək ki, biz rahatlıq url adresimizi düzəldə bilək. Gələcəkdə modelin dəyişəcəyini nəzərə alaraq servisimizi ümumiləşmə(generic) formasında yazırıq.

 public class CbarExchangeService : IExchangeService where T:class
    {
       
        public async Task GetExchangeDatasByDate(DateTime dateTime)
        {
            T c = default;

            //building url for cbar
            string url = new ServiceUrlBuilder()
                                .AddBaseUrl(ConfigurationManager.AppSettings["baseUrl"])
                                 .AddUrlSegment(dateTime.ToString("dd.MM.yyyy"))
                                  .AddServiceExtension("xml")
                                     .Build();

            //preparing to serialize..
            XmlSerializer _xmlSerializer = new XmlSerializer(typeof(T));
            using (var serviceData = await new HttpClient().GetStreamAsync(url))
            {
                c = (T)_xmlSerializer.Deserialize(serviceData);
            }
            return c;
          
        }
    }

 Yekunda isə alınacaq proyektimiz belə görünür:

Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

Müəllifin bu dildə ən son postları

Bu yazıları da bəyənə bilərsiniz