Serializing Generic Classes - c#

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.

Related

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.

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.

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.

System.Web.Script.Serialization.JavaScriptSerializer or System.Runtime.Serialization.Json.DataContractJsonSerializer?

What's the difference between the two? Why would you use one over the other?
Found here: http://aaron-powell.spaces.live.com/blog/cns!91A824220E2BF369!150.entry
DataContractJsonSerializer
The primary purpose of the DataContractJsonSerializer is to be used with WCF, since one serialization is a big focus of WCF. Also, it is also better equipped to handle complex classes which have only certain properties available for serialization.
This class is more strongly typed, has more knowledge about the type(s) it's handling and better error handling for badly-formed JSON.
JavaScriptSerializer
This class on the other hand is much better equipped for quick serialization, it's a more cowboy approach. There's less error checking and less control over what properties which are serialized.
Update
As the above link is dead, here is another link: http://kb.cnblogs.com/a/1454030.
Personally, I'd look at Json.NET - this has the advantage of being .NET 2.0 compatible
The JavaScriptSerializer is marked as obsolete in framework 3.5. You shouldn't use it for that reason. However, back to your question. The JavaScriptSerializer doesn't require classes to be marked as [Serializable] or as [DataContract] but the DataContractJsonSerializer does. If you have compiled classes that you can't mark with attributes, you may want to use the older JSON serializer.

Categories

Resources