Well, first we have to be careful with the concept of Serialize, after all, XML is used for a lot of things nowadays and people tend to call it serializing any action that generates an XML, conceptually this is kind of wrong.
According to Wikipedia:
"...serialization is the process of Translating data Structures or
Object state into a format that can be stored"
Wikipedia
In free translation:
"Serialization is the process of translating (or transforming) the state
(usually in memory) of data structures or objects in a
format that can be stored."
That is, you can take an object and generate an Array of Bytes to send over the network, you can generate array of bytes to store in a file on the disk, send parameters of a process over the network to run on another server or simply generate an XML to store on disk or send to a Webservice.
MSDN has other examples of serialization needs, take a look later (MSDN), the important issue here is that serialization should be a method of representing a copy of the object.
There begins the problem of using the serialization classes of . net for other things, also has the problem that often system designers fail to make clear some concepts in the place to which you send the serialized object (usually a subsystem that you have to communicate but, which has not designed).
I have seen cases where the subsystem varied the date culture differently in different places.
Let’s go to an example code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace serialTest
{
[XmlRoot("Casa")]
public class Casa
{
int? id;
[XmlIgnoreAttribute]
public int? ID
{
get { return id; }
set { id = value; }
}
string cor;
[XmlElement("cor")]
public string Cor
{
get { return cor; }
set { cor = value; }
}
//mesmo atributo, duas propriedades.
DateTime dataConstrucaoPadrao;
[XmlElement("dataConstrucaoPadrao")]
public DateTime DataConstrucaoPadrao
{
get { return dataConstrucaoPadrao; }
set { dataConstrucaoPadrao = value; }
}
[XmlElement("dataConstrucaoComCultura")]
public string DataConstrucaoComCultura
{
get { return dataConstrucaoPadrao.ToString(); }
set { dataConstrucaoPadrao = Convert.ToDateTime(value); }
}
//fim do teste de cultura
[XmlElement("Sala")]
public Sala sala;
}
}
Now a smaller class for a child element in the Home XML:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace serialTest
{
[XmlRoot("Sala")]
public class Sala
{
int? id;
[XmlIgnoreAttribute]
public int? ID
{
get { return id; }
set { id = value; }
}
int quantJanelas;
[XmlElement("QuantJanelas")]
public int QuantJanelas
{
get { return quantJanelas; }
set { quantJanelas = value; }
}
}
}
My Main method of the Console application prints XML on the screen:
using System;
using System.Collections.Generic;
using System.Text;
using serialTest;
namespace ConsoleTestSerial
{
class Program
{
static void Main(string[] args)
{
Casa c;
c = new Casa();
c.Cor = "Vermelho";
c.ID = 1;
c.DataConstrucaoPadrao = DateTime.Now;
c.sala = new Sala();
c.sala.QuantJanelas = 2;
c.sala.ID = 1;
string resultSerial = UtilSerial.Serialize<Casa>(c);
Console.WriteLine( resultSerial);
Console.ReadLine();
}
}
}
And the generated XML:
<Casa>
<Sala>
<QuantJanelas>2</QuantJanelas>
</Sala>
<cor>Vermelho</cor>
<dataConstrucaoPadrao>2016-11-03T14:25:17.5677191-03:00</dataConstrucaoPadrao>
<dataConstrucaoComCultura>03/11/2016 14:25:17</dataConstrucaoComCultura>
</Casa>
The code that generates the XML is missing, but I’m going to leave it at the end because basically it doesn’t matter, since I use a generic and static method to serialize or deserialize, the problem is the way I wrote the classes and let’s focus on that.
Starting with the problems:
1. Serialization classes are made to serialize (generate a copy) and try to ensure that you don’t worry about the rest, so they use invariant culture, if you need to vary the culture, do it yourself.
It is no use to set the application and thread culture if the code of the class that will be serialized does not have an adaptation.
See for example the attribute Datetime dataConstrucaoPadrao of the House Class, change your code to use properties, you are using the attributes publicly, besides being an anti-standard, you will have problems serializing because you will need to change the return without changing the data type. Apply refactoring to your code and carry it forward in other projects.
Notice i Gero two interpretations of the attribute in XML, using proprieades, one reflects the culture and the other not, however, are the same attribute.
This is possible because the standard culture is applied when serializing a datetime, but I create a string property that returns the . Tostring of the date, then will be serialized the result of Tostring and not the date, then Tostring uses the culture of Thread before serialize, in my case, en.
So, if you need to generate XML in a specific culture, use a String attribute and return the Tostring attribute.
I know this culture in front, wait a minute.
2. Objects often have attributes that you do not want to send in XML if you are generating it to go to another system.
Note that the ID attribute of my classes needs to exist to identify the object in my system (and probably in the database) but, it is not a useful attribute in my XML (I don’t even put it there).
good, ai is easy, just use [Xmlignoreattribute] and ta all beauty, just not.
First, there is a conceptual problem, my XML is no longer a copy of the object that existed in memory, so I can no longer guarantee that I can reproduce the state of the application before generating XML, if I need to reverse the process, You’ll have trouble knowing who’s who in the database or elsewhere. Then the ID attribute will need to be null on the return, so it needs to be null.
Generally, in these situations there is some field that is part of the business rule that may be used as primary key (CPF, RG, etc).
But, you’re using serialization outside the definition of serialization.
So why should I use these classes? Well, you know whether or not to use.
It is very easy to put an attribute in the class and generate an XML with the generic method, so ease is sometimes better than perfection. A simple application, which will run only for a small table or routine, can be done in a few minutes instead of days.
The problem is usually maintenance.
And finally, the generic class to serialize:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Globalization;
using System.Threading;
namespace serialTest
{
public class UtilSerial
{
public static string Serialize<T>(T dataToSerialize)
{
try
{
CultureInfo n = new CultureInfo("pt-br");
Thread.CurrentThread.CurrentCulture = n;
Thread.CurrentThread.CurrentUICulture = n;
var serializer = new XmlSerializer(typeof(T));
var stringwriter = new System.IO.StringWriter();
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
var xmlWriter = XmlWriter.Create(stringwriter, new XmlWriterSettings() { OmitXmlDeclaration = true });
serializer.Serialize(xmlWriter, dataToSerialize, ns);
return stringwriter.ToString();
}
catch(Exception e)
{
throw e;
}
}
public static T Deserialize<T>(string xmlText)
{
try
{
CultureInfo n = new CultureInfo("pt-br");
Thread.CurrentThread.CurrentCulture = n;
Thread.CurrentThread.CurrentUICulture = n;
var stringReader = new System.IO.StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch(Exception e)
{
throw e;
}
}
}
}
Here many factors are already clear when we look at the code, I think only the issue of culture is worth an addendum.
These methods will generate representations of attributes with different cultures. All attributes / properties that are defined in the class in order to have a return of a standard type (int, string, datetime, etc.) will be represented with invariant culture, those that return some method that uses crop to generate output (usually Tostring), will have their output in the culture being configured in the thread of these methods, in this case, en.
The same goes for the entrance.
Basic concepts:
- [Xmlroot("Room")] - XML root, use in class definition.
- [Xmlelement("color")] - In XML, use on XML nodes.
For attributes that are Generic Object Lists:
- [Xmlarray("Rooms")] - Generates the root attribute of the list
- [Xmlarrayitem("Room")] - generates each item in the list
In this case, if our House class had a list of Rooms:
private List<Sala> salas;
[XmlArray("Salas")]
[XmlArrayItem("Sala")]
public List<Sala> Salas
{
get { return salas; }
set { salas = value; }
}
Well, to finish, using this structure, every time you need to generate an XML of a class just define the attributes and call the methods of the Utilserial class and you are ready.
A good conversation about Marshall Cline’s C++ Serialization.
You need to actually implement the methods or just serialize the class instances?
– Intruso
serealizar the instances of the class.
– fernando tso
I’ve already sent you an answer, you need to consider culture in xml?
– Intruso
opa, bacana. xml culture, not understood !
– fernando tso
Serialization is the act of representing an object (fully) in a serial format, but often one uses an XML for other tasks (sending to a Webservice, etc.) and in such cases, it is necessary that the XML reflects a specific culture, that goes against the concept of representing the object faithfully in the chosen serialization format (XML), there is a problem.
– Intruso
ha understood, need yes!
– fernando tso
Take a look at the answer and see if it fits you
– Intruso