JSON序列化中DataContractJsonSerializer和JavaScriptSerializer的对比
原文:http://aaron-powell.spaces.live.com/blog/cns!91A824220E2BF369!150.entry
When ASP.NET AJAX shipped last year it came with a class do help with converting objects into JavaScript Object Notation (JSON), in the form of the JavaScriptSerializer. This is a great little class which will create a JSON string with no real troubles from any existing class, or convert a JSON string into a .NET object.
But with .NET 3.5 this class was flagged as obsolete with the replacement being in the form of the DataContractJsonSerializer (yeah, that's a mouthful!).
As ScottGu pointed out in a blog post last year the obsoleting of the JavaScriptSerializer isn't logical, especially since it only came in from the ASP.NET AJAX 1.0 release.
Well what's the difference between the two?
The 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.
It also uses Streams to do the reading/ writing, making it a lot more suited for not just web, but for writing to files, etc.
The 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.
So what to use?
Like every time there's multiple options available within the .NET framework there's no clear winner. Obviously the DataContractJsonSerializer is the primary choice, due to the obsolete nature of the JavaScriptSerializer. But as ScottGu stated it'll be around for several .NET versions to come so using it wont cause your application to break on the next .NET drop.
But not so quick, there's an interesting note on the way the serialization occurs, well more importantly, how the Reflection is employed to create the serialized string (or stream).
Lets say we had a class like this:
[Serializable]
public class MyClass
{
public string Property1 { get; set; }}
public string Property2 { get; set; }
public string Property3 { get; set; }
The JavaScriptSerializer is a very brutal, but efficient manner of conversion. Using the above close you'll receive a JSON string like this:
{ "Property1" : "value1", "Propert2" : "value2", "Property3" : "value3" }
Nice, simple, clean JSON. This is very usable in terms of JavaScript, and it's returned nicely as a string from the Serialize method on the class.
The DataContractJsonSerializer on the other hand is a bit tricker. Because it employs streams you need to decode the stream to get it into a string (there's an example of it's usage on Rick Strahl's blog). In addition the string you end up with is a bit different, the above class will result in this:
{ "<Property1>k__BackingField" : "value1", "<Property2>k__BackingField" : "value2", "<Property3>k__BackingField" : "value3" }
Hmm that doesn't look right! Yep, that's not going to convert very well into a JavaScript object. Why did that happen when the JavaScriptSerializer did such a nice job? Well we have to look at the code that is actually generated for our class.
Because we've used the short-hand notation of declaring properties (which are available within the C# 3.0/ VB 9.0 compilers) we haven't specified the variables which the property will store its data within, and this is what the DataContractJsonSerializer looks for.
If you were to have specified the variables to use with the property getter/ setter methods then you wouldn't have the above problem.
So keep these differences in mind when you're looking to do some JSON serialization :)