What is the preferred way to implement serializable classes in C# - c#

I've seen many different ways to serialize objects in C# that I'm not sure which one to use and when.
In the current situation I'm serializing for exposure through WCF so I'm guessing the [DataContract] attribute is the way to go.
Currently I'm reading in some XML, then exposing the resulting object through WCF. So I am deserializing XML for which I have no access to the original classes (therefore I'm rebuilding the class and can implement serialization whichever way I want). Then it has to be serializable for the WCF.
But if [DataContract] is good for this case, then why wouldn't I use it all the time instead of ISerializable, or the [Serializable] attribute?
So a bit of two questions in one, which to use for this problem, and why are there different ways to serialize.

DataContract is a good place to start for basic serializing. But if you want to control exactly how the object is serialized use the ISerializable interface. Also, the data contract attribute does not get inherited, but the ISerializable will
ISerializable has been around since .net 1.1. DataContract was introduced in .net 3.0 to simplify serializing for most cases.

Using ISerializable, by implementing GetObjectData, you can customize the way an object is serialized/deserialized within the object's class without having to create a serializer
If you create a WCF service, I think you should stick to DataContract. One of its big advantages is the opt in (i.e. no bad surprises) mechanism.

Related

How to support object Serialization and Deserialization for changing class structure with .net?

I have an entity class which can change over period of time. As of now, I binary serialization to serialize an object of this class. But if I add a new property to the class, I can't deserialize a stream serialized earlier. I tried if I can use BSON with json.net.
I need to take care of these things:
Memory footprint of serialized data should be low
serialization and deserialization should be fast
Need to provide backward compatibility for data serialized with old entity class structure
One approach I considered is to convert the object to IDictionary before serializing it so that I can set default value to properties that are not matching while deserializing. While this works well, it involves additional step to convert the object to IDictionary.
Has anyone faced this situation? what are the approaches you use?
Actually binary serialization is very flexible. Of course, you can just add [Serializable] attribute to the class and forget about details, but you can also take the full control on serialization by implementing ISerializable interface/by adding methods/attributes which corresponds to the certain steps of serialization/deserialization lifecycle. Considering your question about structure changes, please take a look on the following article.

Non-intrusive XML Serialization techniques?

I have long held the believe that your domain model should not be responsible for serializing itself to XML. I have used the IXmlSerializable interface in the past to control how my objects are serialized but ideally I'd prefer the nuts and bolts of the serialization to live outside the object.
However I've never been able to actually implement this in a clean manner and I was wondering if there was any patterns I was overlooking to make this happen. Basically I want my object model to do it's thing and be oblivious to XML serialization (or any other serialization for that matter) and then handed off to some service that spiders the object and serializes it.
I've tried doing this with extension methods but this falls short when you want to serialize a collection of type object. I've looked at doing it with object wrappers and DTO's that then serialize but then you've got the overhead of maintaining another set of objects and having to create these objects when you want to serialize which again can get messy when you have collections of type object.
The only other thing is using reflection but I'd worry about the processing overheads.
Is there a sane way to do what I'm asking or should I just bite the bullet and make my objects xml aware?
Using the System.Xml.Serialization Attributes is putting the nuts and bolts outside of your code. You are defining metadata and with the exception of optional parameters, no extra code is required. Implementing IXmlSerializable and doing the serialization by hand is error prone and should be avoided. Why? You are defining your data 3 times.
XML Schema
Class
Serialization code
Using attributes, you can scrub step 3.
XML and C# has an impedance mismatch. Like it or not, at some point, you will need to define the serialization to create the right document model.
Arguably, the classes you are serializing should not be performing any work. They are just a data store. Try abstracting your logic away from serialized objects - it may give you a warmer feeling.
Update
If you really, really hate attributes, try using the adapter pattern to serialize your model. The XML code will be in a separate class or assembly and you can work with your model across storage mediums. You will suffer the consequence of having to update the serialization separately when you update your model.

How to Serialize unserializable object in .NET

I have 3-rd party dll. From that I receive an object of some type (I know its interface, but not all the object). That object is not marked as serializable and I'm not related to that libruary development at all.
I want to serialize it to some storage and then receive it from storage with the same state later (public/private, references etc.). I got here one option - make my own serialization mechanism that will act the same as .NET serializers with the only difference - it won't revise serialization attributes.
Is that the best way?
Thanks.
You can use XmlSerializer or DataContractSerializer to serialize types not marked with SerializableAttribute.
There may be other options. And can always go ahead with custom implementation if nothing works for you.
You can make your own class inheriting from that object and serialize it.
OR you can make your own replica of that class and make some explicit (or implicit, but not recommended) conversion methods.

Serializing Generic Classes

I have read around that serializing generic classes is not supported out of the box with XamlWriter.
First I would like to know why? What is harder about generic classes that makes them non-plug-and-play like all the other classes are.
Second, is there a framework that will allow me to serialize my generic class without much work. (My generic class is fairly involved.)
XamlWriter is hardly the standard serialization method (unless something changed and no one told me!). You haven't actually mentioned what kind of format you want to serialize into, but since you mentioned Xaml I will assume Xml.
For this you can use the DataContractSerializer. It shouldn't have any problems with generic types, and isn't very difficult to use at all. Just remember to markup your class with DataContract and DataMember attributes, just as if you were using WCF.

Using an interface in a C# xml web service

How can I use an interface (from which classes implement) in an XML web service?
When I do so, I get a YSOD claiming the interface is not serializable. If I add the Serializable attribute to the interface's class, there's another error which hampers progress (can't remember which).
For the most part interfaces are not serializable without some work. Usually this error is encountered when the class being serialized contains an object that is using an interface as a variable, or some variation of this. For instance, a property like this would throw an error:
[Serializable]
public class TestClass
{
private ICustomInterface _iCustomInterfaceObject;
public ICustomInterface CustomInterfaceProperty
{
get { return _iCustomInterfaceObject; }
set { _iCustomInterfaceObject = value; }
}
}
For the sake of the argument (and not making me type additional validation code), let's say that you always are assigning CustomInterfaceProperty to an object that inherits from ICustomInterface (as is required when using interface types like this). Even if it is 100% sure to always be populated, it won't allow you to serialize the TestClass.
To get around this, you need to make sure the interface you are using, the one that is throwing the error, also inherits from ISerializable. That way you are promising that all of the objects inheriting from ICustomInterface also have serialization methods implemented.
Unfortunately, this is not the case when using xml serialization. If you are using the serializers found in System.Xml.Serialization then this method won't work, since, as Robert Harvey pointed out, an interface does not contain a parameterless constructor (which is required when using the xml serializers). My suggestion for now, if you are set on this method of serialization, attach the attribute [XmlIgnore] to the section in question and move on from there.
My advice is to treat the objects that go over the wire as basic data transfer objects and nothing more. You're tempted to just use your domain objects and serialize them, but as you're already seeing, normal in-memory objects can have far more complexity than can be serialized without a lot of work, and sometimes not at all.
You can also end up limiting functionality of your domain classes just to keep them serializable.
Finally, a more subtle bug to avoid, and a reason to have separate DTO's, is that you otherwise are tightly coupling your domain objects to a publicly published interface i.e. the web service itself. Versioning a web service can be a hassle, and it's easier if your service interface isn't tightly coupled to your domain classes.
I'm guessing that the other message is that you can't serialize the interface because it doesn't contain a default (parameterless) constructor.
If the underlying classes are framework classes, you might be hosed. Some of them are not marked serializable, and some of them do not have parameterless constructors.
Also, you may be getting confused between runtime serialization and XML serialization. XML Serialization is what the old ASMX web services use. It does not pay much attention to the [Serializable] attribute, but mostly just serializes the public read/write properties of public classes which have a default constructor.

Categories

Resources