C# Object Serialization Changes - c#

I have the following issue:
My object is being serialized as follows:
MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, _policy);
CaptureData = Convert.ToBase64String(memorystream.ToArray());
And then saved to my database and de-serialized as required from the data saved in the database.
My problem now is that I can't make changes to this object, add properties etc as this breaks the deserialization.
Any suggestions on how I can add properties without breaking serialization of previous objects?

I don't think it's possible using this serializer.
If possible, use another serializer that deals with backward compatibility like protocol buffers

You can use [OptionalField] and similar to take advantage of the version tolerant serialisation built into .Net.

You need to shift from the built-in serialization , as this is, as you saw, is rigid and not scallable. Pick any other serializaiton technique that let's you maintan scallability of your types and flexibility of your system.
custom binary serialization
xml serialization
json serialization
binary serialization with protobuf (just example...)
All this, if you can do that. If not, for some architectural (historical) restrictions, just can do something like suggested in Hamlet's comment. But it sounds like a rough solution to me.

Related

C# Serializing properties with custom values

I want to serialize a class with a lot of properties. Some of those properties are complex. There are some of the type Bitmap, Color and much more, and they do not get serialized at all.
The approach I am using is the following:
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
MemoryStream stream = new MemoryStream();
serializer.Serialize(stream, obj);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
XmlDocument returnDoc = new XmlDocument();
returnDoc.Load(stream);
How can I create "custom" approaches for those complex properties? Until now I created the XML-Documents myself and went trough every single property and converted it to text.
An other example where I need this is on references. This class has got some references to other classes. I don't want the whole subclass to be serialized, but only the name of it.
I am sure there are different approaches on how to accomplish this. What would be the best way to go?
I already tought of making extra properties and ignoring the others (XmlIgnore()), but that would be an overhead.
Thanks!
Your best bet is to stop trying to serialize your domain model, and create a DTO model that represents just what you want to store, in the way you want to store it (i.e. geared towards your chosen serializer).
If you want to store a bitmap, then you probably want a byte[] property. If you want to store the name of something - a string. Then just map between them. Simple, pain-free, and much easier than trying to fight a serializer into doing something that it doesn't want to do.
For properties that are not serializable you need to implement the serialization yourself. You could serialize these objects to a byte array and then use Base64 encoding to place them to XML. Check out the following link: XmlSerializer , base64 encode a String member.
However, if you do not need to serialize into XML, you can use binary serialization which will work on all properties.

Saving a collection of SerializableAttributes

I have several Employee objects which are all SerializableAttributes. This is due to WCF, because these are objects passed between the client and the server.
I would now like to save and load several of these, either to a file or by using System.Properties namespace. With the System properties, I could not find a way to save them because the types that are allowed are pretty limited: int, string, float and some others. There's nothing involving serializable, and the only collection available is a string collection.
What would be the best approach? I'm not sure what is the proper way to save a collection, like List<> of SerializableAttributes to a file. Otherwise, I can use System.properties and I could do it the "hard way" by converting the objects to strings and back, but this approach will be pretty ugly.
You have many alternatives such as: JavaScriptSerializer XmlSerializer DataContractSerializer DataContractJsonSerializer BinaryFormatter SoapFormatter.
(BTW: Serializable attribute is only used by BinaryFormatter and no need for WCF)

C# Persisting Objects Between User Sessions Without using a database

I'm making a simple Winforms that reads in a text file and does some parsing to put it into C# objects that are then manipulated by my app.
I would like to parse the file once. Then go away for a week, come back and load all the objects back into my app.
I don't want to persist to database thus was hoping there was some sort of simple object persistance framework I could hook into.
You are talking about serialization.
Look into the DataContractSerializer for this. If you want a file that isn't XML you can try the DataContractJsonSerializer.
You simply add the DataContract and DataMember attributes to tell the serializer how to manage the serialization.
If your objects will not change (new/old/renamed properties and visibility) and you don't care to read the serialization format, you can try the BinaryFormatter.
There are several older serializers in the frame work (XmlSerializer, BinaryFormatter and more), but the best control over the serialization format will be with the above).
You could use application settings or user settings. Its pretty easy with the wizard that can be found under the projects properties. here is the tutorial for it.
You could just serialize them to an XML file. Simple, quick and easy (unless someone hacks the file).
The simplest non-DB method of storing object state is serialization. Mark your class as either Serializable or a DataContract, then use a BinaryFormatter (or DataContractSerializer if you used the DataContract) to convert the object into a persistable state. That can then be saved to a file that you can load when the app starts back up and deserialize in a similar fashion. Be aware that the class's members, including child classes, must be serializable in the same way, and that you will lose any references to non-serialized elements such as pointers and delegate references.
You can use serialization as sugested before.
A good place to save the data in is Windows's LocalData folder -
Environment.SpecialFolder.LocalApplicationData
Probably the simplest way to do this would be to serialize the objects directly to a file, using the BinaryFormatter class. You'll need to make sure that all your types are marked as [Serializable] but this approach is fast and easy.
Here is a simple example of a "read" and "write" method for an arbitrary object graph:
private void SerializeToFile(string fileName, object o)
{
var binaryFormatter = new BinaryFormatter();
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
binaryFormatter.Serialize(fileStream, o);
}
}
private object DeserializeFromFile(string fileName)
{
var binaryFormatter = new BinaryFormatter();
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
{
return binaryFormatter.Deserialize(fileStream);
}
}
Other approaches include XmlSerialization (the XmlSerializer class) - better if you want to the serialized objects to be human readable or editable, or using the newer DataContractSerializer.
What is wrong with a database ? If you do not want to have a full engine with its setup and associated problems, maybe you can take a look at "file" based databases...
My first toughs are :
SqlCompact
Access databases
SqlLite
...
Depending the complexity of your objects to persist, it can be a good solution.

Write CLR objects to XML with LINQ

I have an ObservableCollection items. I want to convert these to XML format so that I can store them for later use. I'm a little new to LINQ and I'm not sure how to do this. I know that I need to rely on the XDocument. But I'm not sure how to execute the query and get the results into a string format.
Can somebody please provide some pointers for me? It just seems like such an easy task, I'd be surprised if it couldn't be done.
Thank you,
You need Linq to XML. I can't post a real code here since I don't know the structure of your data, but here's a dummy example:
List<Person> people = ...
var doc = new XDocument(
new XElement("People",
from p in people
select new XElement("Person",
new XAttribute("Id", p.Id),
new XElement("LastName", p.LastName),
new XElement("FistName", p.FirstName))));
doc.Save("people.xml");
Note that Linq is not the only option here. Another very good approach is XML serialization.
Using the DataContractSerializer is your best bet. It's designed to do exactly what you are asking for.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer(v=VS.95).aspx
Advantages over XMLSerializer:
Opt-in rather than opt-out properties to serialize. This mean you specify what you want serialize
Because it is opt in you can serialize not only properties, but also fields. You can even serialize non-public members such as private or protected members. And you dont need a set on a property either (however without a setter you can serialize, but not deserialize)
Is about 10% faster than XmlSerializer to serialize the data because since you don’t have full control over how it is serialize, there is a lot that can be done to optimize the serialization/deserialization process.
Can understand the SerializableAttribute and know that it needs to be serialized
More options and control over KnownTypes
Disadvantages:
No control over how the object is serialized outside of setting the name and the order
I'm not sure what you want.
You can create a XElement and convert it to a string with the ToString method.
You can do the same with XDocument.
I'm not at all familiar with Silverlight, but it sounds like you are going to need to use XML serialization. XML serialization allows you to serialize an object into an XML representation, which you can then later deserialize from XML back into an object.
Here are some tutorials and information on XML serialization in .NET:
XML Serialization
XML Serialization Using C#
XmlSerializer class

Serialize C# class directly to SQL server?

can anyone suggest the best way to serialize data (a class actually) to a DB?
I am using SQL server 2008 but i presume i need to serialize the class to a string / or other data type before storing in the database?
I presume that this field needs to be text or binary??
Does SQL server 2008 (or .net 3.5) support serializing directly tothe database ??
Any help really appreciated
You can xml serialize the class into an xml field. We use this all the time for exception logging in an ETL.
Using the XmlSerializer you may want a helper method somewhere which serializes the class to a string...
public static string SerializeToXml<T>(T value)
{
StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, value);
return writer.ToString();
}
Then just put the string into the db like any other.
The best way to store data in a database is in columns (per property), so that it is queryable and indexable. ORM tools will help with this.
However, it is also possible to serialize a class as a CLOB/BLOB (varchar(max)/varbinary(max) etc).
It this is what you want, avoid anything implementation-specific or version-intolerant; so in particular, don't use BinaryFormatter. Anything contract-based should work; XmlSerializer, DataContractSerializer, etc. Or for fast binary, protobuf-net might be worth a look.
But I stress; columns would be better.
Without generics (better sollution)
public static string SerializeToXml(object value)
{
StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
XmlSerializer serializer = new XmlSerializer(value.GetType());
serializer.Serialize(writer, value);
return writer.ToString();
}
I've serialized objects as XML and thrown those into the database just fine. Since we knew the max amount of text we used the varchar(max) datatype instead of getting into TEXT or Binary formats.
This was a OLTP web application and one thing we found was that using a column with an xml datatype invoked some significant cpu usage as the xml was validated on every insert. In our case the xml was never queried for anything so not having the xml query capabilities worked out ok for us.
There are couple of options:
Runtime serialization, serializable objects are marked with the
Serializable attribute, in which case the IFormatter class does all the work of
serialization. A serializable object can ISerializable, but then you will
need to implement the GetObjectData( ) method. The problem with runtime serialization is that program reading the xml data needs to have
the knowledge of the CLR types.
Xml serialization: Unline runtime serialization, you will get good interoperability in this case.
The XmlSerializer type contains the methods Serialize( ) and Deserialize( ), thus
any object can be serialized to XML and saved into the database and when you retreive it back, you
can deserialize it easily.
To read data from the database, you can use the SqlCommand class
method that executes SQL queries, namely ExecuteXmlReader( ).
ExecuteXmlReader( ) returns an instance of XmlReader and that will read your xml data.
Check out Linq-to-SQL (questions on SO, resource on MSDN) or other O-R Mapping options.

Categories