How to Serialize unserializable object in .NET - c#

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.

Related

Why SerializationAttribute is not applied by default? [duplicate]

Based on my understanding, SerializableAttribute provides no compile time checks, as it's all done at runtime. If that's the case, then why is it required for classes to be marked as serializable?
Couldn't the serializer just try to serialize an object and then fail? Isn't that what it does right now? When something is marked, it tries and fails. Wouldn't it be better if you had to mark things as unserializable rather than serializable? That way you wouldn't have the problem of libraries not marking things as serializable?
As I understand it, the idea behind the SerializableAttribute is to create an opt-in system for binary serialization.
Keep in mind that, unlike XML serialization, which uses public properties, binary serialization grabs all the private fields by default.
Not only this could include operating system structures and private data that is not supposed to be exposed, but deserializing it could result in corrupt state that can crash an application (silly example: a handle for a file open in a different computer).
This is only a requirement for BinaryFormatter (and the SOAP equivalent, but nobody uses that). Diego is right; there are good reasons for this in terms of what it does, but it is far from the only option - indeed, personally I only recommend BinaryFormatter for talking between AppDomains - it is not (IMO) a good way to persist data (to disk, in cache, to a database BLOB, etc).
If this behaviour causes you trouble, consider using any of the alternatives:
XmlSerializer, which works on public members (not just the fields), but demands a public parameterless constructor and public type
DataContractSerializer, which can work fully opt-in (using [DataContract]/[DataMember]), but which can also (in 3.5 and above) work against the fields instead
Also - for a 3rd-party option (me being the 3rd party); protobuf-net may have options here; "v2" (not fully released yet, but available as source) allows the model (which members to serialize, etc) to be described independently of the type, so that it can be applied to types that you don't control. And unlike BinaryFormatter the output is version-tolerant, known public format, etc.

How can I serialize objects that inherit built-in c# classes?

I'm trying to create a function that will save the current state of my application to a file, and another function to load a saved file. Currently, all the information is contained within a single object, which in turn refers to other objects. I recently heard that C# has some built-in classes that help you serialize and deserialize your objects, so I did a little research and learned about DataContracts, mostly from this page: http://msdn.microsoft.com/en-us/library/ms731073.aspx
Most of it works, except for the classes that implement built-in classes. For example, I have an object that inherits System.Windows.DependencyObject, and when I try to serialize it, it complains that my class inherits a class that does not have the DataContract attribute.
It makes sense to me why that would be a problem. When an object is being deserialized, its constructor is not called. If it inherits something that is not serializable, that might leave it in an invalid state.
I was wondering if this was possible: can I somehow tell the deserializer to call the base class's default constructor before deserializing my object? And then I would have to tell the serializer not to freak out.
Can you create a data transer object that has all the properties you want to store, then populate that object with data from the framework object? Mark it as serialized, fire up the serialization class of your choice - and now you have all the info you need. You just need to re-populate the appropriate class after deserialization.
You may want to look into using a binary serializer or xml serializer instead of a data contract serializer for this one. If you're saving it to a file and don't need the file human-readable binary serialization nearly always works.
See Binary Serialization, and in particular the Basic Serialization topic.
Also take a look at the XmlSerializer Class which will sometimes work where a DataContractSerializer doesn't.

Control object creation during deserialization

I would like to control object creation of a type that is not usually serializable during deserialization using a NetDataContractSerializer (or any serializer I guess). Using a custom SerializationBinder I can control the type that is constructed and using a custom ISurrogateSelector and ISerializationSurrogate to control how state is set on the object.
What I cannot do is actually create the object myself to allow the use of dependency injection or something. The object that is causing problems is inside the object graph so I cannot edit it before serialization.
Is there a way to allow my code to construct the deserialized object?
(For background, I am writing a custom WF4 persistence instance store based upon the XmlWorkflowInstanceStore in the WF samples. I want to author workflows that have variables that are interfaces... and the concrete types cannot be constructed directly. The XmlWorkflowInstanceStore is the only example I can find of custom persistence and it uses a NetDataContractSerializer to serialize the workflow state.)
I run into this problem all the time. I normaly implement ISerializable myself and set all the dependencies with an method (named for example SetDependencies) - this is not truly the way you might want (because you have to call it after deserialization) but I didn't find a better way yet (tried AOP but it went to nasty)
I know this question is old, but were you looking for GetSafeUninitializedObject?

What is the preferred way to implement serializable classes in 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.

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