Skip to main content

Posts

Showing posts with the label serialization

DataContractSerializer and list of abstract class

Plecam de la urmatoarea structura: public abstract class BaseCar { public string Name { get; set; } } public class SportCar : BaseCar { } public class UtilityCar : BaseCar { } public Foo { public Foo() { Cars = new List<BaseCar>(); } public List<BaseCar> Cars { get; set; } } ... Foo myFoo = new Foo(); myFoo.Cars.Add( new SportCar()); DataContractSerializer serializer = new DataContractSerializer(typeof(Foo)); serializer.WriteObject(myXmlWriter, myFoo); Cand nu avem specificat nici un atribut de tip DataContract, toate campurile care sunt publice se serializeaza. In cazul nostru codul se compileaza fara probleme si obtinem un obiect serializat. Problema apare cand vrem sa deserializam obiectul nostru si ne trezim ca proprietatea Cars este null. Chiar daca in constructor inializam aceasta proprietate obtinem in continuare NULL. Cand ne uitam peste cod realizam ca lucram cu o clasa abstracta, iar in acest caz avem nevoie de atributul KnownTypes pe care il si ad...

DataContract and XMLIgnore attribute

Intr-un post anterior am discutat despre cum putem sa serializam un IDictionary in format XML. In mod normal o clasa care nu este decorata cu atributul DataContract o sa poata fi serializata folosind DataContractSerializer fara nici o problema. In acest caz, toate proprietatiile si field-urile publice o sa fie serializate. In specificatiile la DataContractSerializer, ne este specificat ca orice atribut folosit pentru serializare in format XML (XmlIgnore, XmlArray, Serializable etc.) sunt ignorate. Totusi cand obiectul de mai jos era serializat, atributul XmlIgnore este luat in considerare. public Foo { public string Name { get; set; } [XmlIgnore] public string Value { get; private set; } } In prima faza cea ce se intampla este destul de ciudat. In mod normal acesta nu ar trebui sa fie ignorat, dar practic proprietatea este ignorata in totalitate. In realitate DataContractSerializer functioneaza asa cum ne-am astepta. Dar ...

Cannot serialize member ... because it implements IDictionary

Cat de cunoscuta vi se pare urmatoarea eroare: Cannot serialize member [FooMember] ... because it implements IDictionary. Primul lucru pe care oamenii il spun cand intalnesc aceasta eroare este: "Pai logic ca crapa, un dictionar nu e serializabil". Da, intr-o oarecare masura enuntul de mai sus este adevarat, dar nu in totalitate. Nu toate serializatoarele sunt capabile sa serializeze un IDictionary. Cele mai dese probleme de acest gen apare cand se lucreaza cu XmlSerializer. Trebuie tinut cont ca aceasta problema nu apare la serializare ci la deserializare. Deserializatorul nu stie cu ce obiecte lucreaza, nu gaseste nici o informatie despre tipul lor. O solutie destul de simpla, care este la indemana oricui este sa folosim DataContractSerializer pentru a serializa/deserializa un dictionar. Schimbariile care trebuie facute pentru a trece de la XmlSerializer la DataContractSerializer sunt destul de putin. Primul pas este sa marcam clasa pe care o dorim sa o serializam cu DataCo...

Adnotare enum cu mai multe valori

Cand dorim sa serializam un enum putem sa atasam la valoarea fiecarui item din enum atributul XmlEnumAttribute . Astfel la serializare/deserializare o sa putem lucra cu o valoarea string nu cu o valoare numerica. Pana aici nici o problema, dar cum facem sa obtinem doar aceasta valoarea si nu un xml care contine si aceasta valoarea . De exemplu pentru enum-ul: public enum Dimension { [XmlEnum(Name="BigT")] Big [XmlEnum(Name="SmallT")] Small } am obține folosindu-ne de XmlSerializer un output care contine si un nod care specifica ce tip de data ii. Pentru a putea sa obtinem doar valoare BigT sau SmallT putem sa apelam la reflection si sa iteram prin atributele item-ului respectiv pana ajungem la un atribut de tip XmlEnumAttribute . Acuma, daca ducem problema umpic mai departe, putem sa ajungem la cazuri in care elementele din enum au diferite valori. De exemplu daca lucram cu doua sau mai multe aplicații, putem sa avem doua sau mai multe reprezentări...

MSMQ - mesaje in format XML

MSMQ este folosit foarte des folosit în aplicațiile destok pentru a comunica intre doua sau mai multe procese. Citirea si scrierea unui mesaj in MSMQ se face extrem de simplu: //Creare de mesaj. System.Messaging.Message message = new System.Messaging.Message(); message.Body = "some text"; message.Label = "Test message"; //Initializare MSMQ. var msmq; if(MessageQueue.Exists(@".\Private$\NumeQueue")) { msmq = new System.Messaging.MessageQueue(@".\Private$\NumeQueue"); } else { msmq = MessageQueue.Create(@".\Private$\NumeQueue"); } /Trimitere mesaj msmq.Send(message);. /Citire mesaj. try { message = mq.Receive(new TimeSpan(0, 0, 10)); } catch { //Executa ceva in caz de eroare. } Pentru a primii un mesaj, putem sa ne inregistram la evenimentul "ReceiveCompleted" a unui MessageQueue. Daca o sa încercam sa trimitem prin MSMQ un mesaj cu conținut XML de genul: <Text> <Valoare>Test</Valoar...