|
|
Comments and Discussions
|
|
 |

|
If any one can make fastJSON faster I am all ears
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hi Mehdi,
nice work! I run though into a problem, when I tried to deserialize a JSON into a polymporphic objects. My object model is similar to city => list<zoo> => list<animals>
Since I don't know what animals are within a zoo, I just have a type animal for each zoo. The problem is now, that only animals of type animal are created and not dogs, cats, etc.
Now, I would like to solve this problem through a custom type animal, in which I can check the supplied json for the necessary properties for each animal (dog barks, cat miaus, etc.)
The issue is now, that the current implementation (2.0.9) passes only a string to the custom deserializer and throws an error, if the custom type consist of multiple properties or additional object. I was now wondering if this could be changed to the passed parameter from string to a dictionary or full json object.
thanks for your feedback,
Chris
|
|
|
|

|
Thanks Chris!
"Custom Types" is intended for RECT, COLOR, ... etc. not for classes. fastJSON will automatically handle nested types for you if you have enabled the extensions (and given the dog inherits from animal).
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
hi Mehdi,
thanks for the quick response. The Problem is that those nested types defined as follow in JSON:
A point:
{ "geometry" :
{ "x" : 2781859.5718259001,
"y" : 5104563.3898882624
}
A polygon:
{ "geometry":
{ "rings":
[
[
[123.445, 23.456],
[33.123, 23.4345,
[33.125, 23.4345,
[123.2342, 23.4345]
],
[
[123.445, 23.456],
[33.123, 23.4345,
[33.125, 23.4345,
[123.2342, 23.4345]
]
]
}
}
(PS: I know, this is not best way to do this, but it was given to me as such and can not be changed )
I would need now to create a GeometryPoint and GeometryPolygon object, which belongs to a dataset which has a property Geometry (which can be point or polygon).
==> Dataset.Geometry could be of type GeometryPoint or GeometryPolygon (and both inherite from the base type Geometry)
I believe, that for this purpose I would need a custom type with needs to be able to parse the appropriate JSON substrings, yet those substrings need to be passes as Dictionary. Therefore my question regarding the passed type.
Unless, there's another approache to this problem?
thanks for your help,
Chris
|
|
|
|

|
Ah! the data does not have the $type extensions...
Try the Parse() method instead, it will give you a dictionary and list of object collections.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hi Mehdi,
We are planning to use your work in our company. In that scope, I have done some major code review. For now, I can offer you two different packages, if you are interested: a small one and a big one.
The first is primarily focusing on the public API applies primarily minor code review changes. This should definitely a value to the community. Performance characterisics should not have been changed.
The second package is an intense review, in brief details:
- Harmonizing with .NET naming conventions
- Applying good principles like separation of concerns (with perf. in mind).
- Improving exception reporting
- Increasing flexibility of the framework: Property opt-in, Property opt-out. This should increase performance in real-life use cases.
- Small performance drop 1-3% (custo types always available)
- Unit test driven: all native serilization/ deserialization is tested (46+ Tests)
- 5+ Bug fixes
- Improved debugging capabilities
In the near future, I will have to make the basic funcionality again available under Silverlight 5. Which critical feature was removed by Microsoft?
Best Regards,
Aron
|
|
|
|

|
Thanks Aron!
Anything which doesn't break usage is most welcome (I would like to change somethings but it would break running code for people). Post your changes to me or you can fork the code for yourself and publish that way.
As for SL5, the code that doesn't exist is (in Reflection.cs):
...
DynamicMethod dynamicSet = new DynamicMethod("_", typeof(object), arguments, type, true);
...
I'm a bit put off by MS in this regard so I haven't put any time into creating a workaround for it.
[as a side note fastJSON works as is in MonoDroid, and I will publish soon ]
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Sorry Mehdi for the late response,
but I am quite busy during the week. For now, I don't want to post a public alternative. Therefore, I have uploaded the packages to a different server.
The first package was about code understanding and improving without changing or breaking stuff.
http://www.innotags.de/download/fastJSON.zip[^]
The second package is about bringing value to the code, improving and hardening it.
Performance:
===============================================
I have run additional performance tests on that package and I am not perfectly happy:
- I lost 10% during serialization. Maybe you could have a quick look, if there is an obvious mistake.
- Deserialization is equal, sometimes faster but not significally.
Abstract from the readme.txt
===============================================
The changes are basing on FastJSON 2.0.9
- All native non-exotic members are unit tested in serialization/ deserialization
- 'Json' class is tested with the complex class used for unit testing.
- NOT COVERED BY TESTS YET:
- JsonParameter interpretations
- $type support
- I had to change the namespace to something in order to be able to compare with FastJson 2.0.9
- The benchmark console app has also been adjusted slightly.
NEW FEATURES
===============================================
- Property Opt-in, Opt-out: See JsonParameter.SerializationPolicy. To be combined with DataMemberAttribute. I have choosen this attribute over Serializable attribute since the last is coming from System.Xml, DataMember from Runtime.Serialization. Performance hit first time the type is used.
- Added support DataMember.Name which allows to declaratively abstract the json field name from the property name which increases robustness of the resulting json protocol. It will also easy the case-insensitive implementation a lot I think. Performance hit first time the type is used.
- Added support for IgnoreDataMember. Useful for Opt-out scenarios. Performance hit first time the type is used.
- Added support for encoding, see JsonParameters.Encoding. Performance hit depending on the encoding used (no hit, if default encoding is used).
FIXED ISSUES
===============================================
- Benchmark: Using StopWatch instead of DateTime which is recommended to measure ellapsed time.
- JsonSerializer: DateTime to Utc is now respecting the kind of the datetime (JsonSerializer_DateTimeUtc)
- JsonSerializer: List of bytes was not properly serialized (see JsonSerializer_ByteEnumeration)
- JsonPropertyInfo.CanWrite (formerly named MyPropInfo) was always false for fields (should be always true).
- JsonPropertyInfo.Filled was never false. Returned by Reflection, which always sets it to true. Don't see the use of the variable. Removed.
- JsonPropertyInfo.GenericTypes was always null except for dictionaries with the name "Dictionary".
PENDING ISSUES
===============================================
- Benchmark mistake in BinaryFormatter: as you mention fastJSON based on streams is a lot slower. The BinaryFormatter consumes streams so it cannot directly be compared to FastJson. The use cases are different: in case of an http request for instance, the input value is 'stream' and not 'string'. In order to compare performance, the Json Benchmarks should also have the input value 'stream' and not string. The time to convert the input value have to be paid anyway -and it should be part of the FastJson Benchmark which is not the case.
- JsonDeserializer deserialization of byte[] is still failing, see Json_ByteEnumerationClass
- JsonRegistry is not threadsafe: changing ShowReadOnlyProperty has potential to corrupt running (de-)serializations. Should be removed. Unit tests reveal that the issue exists also in a single thread.
- There is a bug in the $type extension. It has a risk of return the wrong type. One can see it when exotic benchmark is run which will report an InvalidCastException.
Best Regards,
Aron
|
|
|
|

|
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
var manager = new ExpandoObject() as IDictionary<string, object>;
manager.Add("Name", "Allison Brown");
manager.Add("Age", 42);
Console.WriteLine(((string)fastJSON.JSON.Instance.ToJSON(employee)));
Console.WriteLine(fastJSON.JSON.Instance.ToJSON(manager));
Console.WriteLine(((string)ServiceStack.Text.JsonSerializer.SerializeToString(employee)));
Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(manager));
Output:
{"$types":{"System.Dynamic.ExpandoObject, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"1"},"$type":"1"}
{"$types":{"System.Dynamic.ExpandoObject, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"1"},"$type":"1"}
["[Name, John Smith]","[Age, 33]"]
{"Name":"Allison Brown","Age":42}
|
|
|
|

|
Thanks Alexandre!
I have had a couple of requests for "dynamic" support.
PRO's:
- a better coding experience
- you don't need to create the containing class (less coding)
CON's:
- requires .net4+
- a bit slow
Having said that I may add it as a better Parse() method for .net 4+ compilations.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I have a anoying problem.
I am getting this error now. It has been working before in other projects but not in my recent.
This is a test code that is thowing the error:
Public Class fastJSONBuggTestC
Public Settings As New SettingsC
Public Class SettingsC
Public Version As Integer = 1
Public RegistrationKey As String = "unknown"
End Class
Public Sub New()
Dim testSettings As New SettingsC()
Dim param As New fastJSON.JSONParameters()
param.IgnoreCaseOnDeserialize = True
param.SerializeNullValues = True
param.UseExtensions = True
param.UseFastGuid = True
param.UseOptimizedDatasetSchema = True
param.UseUTCDateTime = True
param.UsingGlobalTypes = True
Dim jsonString As String = fastJSON.JSON.Instance.ToJSON(Settings, param)
Settings = fastJSON.JSON.Instance.ToObject(jsonString)
End Sub
End Class
It is this row:
Settings = fastJSON.JSON.Instance.ToObject(jsonString)
that is throwing the error "Cannot determine type", anyone now why this is hapening now and not before?
Thanks!
Robin Andersson
|
|
|
|

|
Can you send me the JSON string generated?
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Extremely through and highly optimized
|
|
|
|

|
A couple of examples:
One:
["foo0",{"foo1":"C:\\!bar1","foo2":"C:\\bar2"}]
[
"foo0",
{
"foo1" : "C:\\!bar1",
"foo2" : "C:\\bar2"}]
Two:
[{"foo":"'[0]"}]
[
{
"foo" : "'[
0
]"}]
|
|
|
|

|
Hi,
great work and I'd really appreciate it if you try to update the NuGet package regularly. So everyone can update to the latest version easyly.
Thanks a lot
|
|
|
|

|
I will try
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Thanks. 5-stars
|
|
|
|

|
like:
var arr2 = new[]{
new { Text = "M", Value = true},
new { Text = "F", Value = false }
};
var ttt = fastJSON.JSON.Instance.ToJSON(arr2, new fastJSON.JSONParameters() { UseExtensions = false });
the result is : "[{},{}]"
|
|
|
|

|
Actually it will serialize but *not* deserialize anonymous types, just set the EnableAnonymousTypes = true parameter.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hello,
I run the console test and it appears that deserialization of dataset is not working.
Was it working in a previous version?
Tkanks a lot.
|
|
|
|

|
What error are you getting?
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Thans for your answer.
The error is "Cannot determine type"
The code who provide error is:
ds = CreateDataset();
string text = fastJSON.JSON.Instance.ToJSON(ds);
DataSet ds2 = (DataSet)fastJSON.JSON.Instance.ToObject(text);
If the dataset is a property of an object, it's working.
But if the Dataset is the object it doens't work.
|
|
|
|

|
Root level deserialize of a dataset is not supported at the moment. The code will work fine if the dataset was in an object.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I have added root level DataSet and DataTable support and will post shortly.
var ds = CreateDataset();
var s = fastJSON.JSON.Instance.ToJSON(ds);
var o = fastJSON.JSON.Instance.ToObject<DataSet>(s);
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
For example i have code in c#:
public class TestB
{
public int b = 3;
public string c = "AA";
public TestB() { }
};
public class TestA
{
public int a = 0;
public TestB tb = new TestB();
public TestA() { }
};
void method()
{
WebRequest webRequest = WebRequest.Create("http://localhost/");
webRequest.ContentType = "application/json";
webRequest.Method = "POST";
TestA ta = new TestA();
string a = JSON.Instance.ToJSON(ta);
byte[] bytes = Encoding.UTF8.GetBytes(a);
Stream os = null;
webRequest.ContentLength = bytes.Length; os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
if (os != null)
{
os.Close();
}
WebResponse webResponse = webRequest.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
string s = sr.ReadToEnd();
TestB tb = JSON.Instance.ToObject<TestB>(s);
}
and i have a server in php v. 5.3 to response this:
$data = file_get_contents("php://input");
$obj = json_decode($data);
$ret = json_encode($obj->tb);
$len = strlen($ret);
header("Content-length: $len");
echo $ret;
return;
So in the class is return inner value of class TestB (tb). Send is ok, it sends $types, and $type. But in return it send me:
{"$type":"2","b":3,"c":"AA"}
Doesn't send information about types ($types), and in your code the value of globaltypes
is empty because the return information is $types and code will have exception on line:
if (globaltypes.TryGetValue((string)tn, out tname))
tn = tname;
|
|
|
|

|
Hi, I have a exception while parsing a json string which contains numbers formatted as:
Points": [
{
"X": 0.1097,
"Y": 0,
"Z": 4.16366160299608e-18 // <- bug here
}
]
To fix it, in JSONParser.cs (line 308, function ParseNumber()) , replace:
return decimal.Parse(s,NumberFormatInfo.InvariantInfo);
with:
return Double.Parse(s,NumberFormatInfo.InvariantInfo);
Thanks.
Alex.
|
|
|
|

|
Unfortunately the GermanNumbers test fails with this.
I will try to find a work around.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Fixed now in v2.0.8.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Thanks !
I'll test it now.
|
|
|
|

|
First of all, thanks for sharing that little useful library! I just wonder why doesn't it support deserialization of arrays (admittedly, you can use List, but still)? The necessary code changes seem to be trivial.
Regards,
Andrew
|
|
|
|

|
Thanks Andrew!
The following works fine:
public class arrayclass
{
public int[] ints { get; set; }
public string[] strs;
}
[Test]
public static void ArrayTest()
{
arrayclass a = new arrayclass();
a.ints = new int[] { 3, 1, 4 };
a.strs = new string[] {"a","b","c"};
var s = fastJSON.JSON.Instance.ToJSON(a);
var o = fastJSON.JSON.Instance.ToObject(s);
}
I have added it to the unit tests.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|
|

|
Good tips
|
|
|
|

|
¿It is possible to deserialize immutable classes?
If i have a class like this:
class Immutable
{
public Immutable( long id )
{
this.Id = id;
}
public long Id { get; private set; }
}
with JsonNet i must add a attribute to them and an empty constructor and leave the class like this:
class Immutable
{
[JsonConstructor]
private Immutable() : this(0) { }
public Immutable( long id )
{
this.Id = id;
}
[JsonProperty]
public long Id { get; private set; }
}
Thanks
Iker eL_FRuTeRo
|
|
|
|

|
You don't need any attributes with fastJSON, but a default constructor is required.
You can get the json output for readonly properties by setting the ShowReadOnlyProperties = true in JSONParameters.
Obviously when deserializing the readonly properties will be ignored and not set.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
In a immutable object, all its properties are readonly as they are immutable.
can i deserialie them without adding a public setter?
Thank you very much
Iker eL_FRuTeRo
|
|
|
|

|
Unfortunately not since the deserializer is using the Set method defined on the class and if it is private then it will fail.
Obviously the designer of the class made the decision to make properties private, so it is unsafe to assume anything about the internal structure of the class when reflecting at the level of fastJSON.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I am trying to serialize and deserialize a variable of type System.Type. Is that possible? If yes, what am I doing wrong?
System.Type type = typeof(string);
var jsonText = JSON.Instance.ToJSON(type);
var newType = JSON.Instance.ToObject(jsonText) as Type;
I get the following exception:
System.Exception : Failed to fast create instance for type 'System.RuntimeType' from assemebly 'System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
----> System.ArgumentNullException : Value cannot be null.
Parameter name: con
at fastJSON.JSON.FastCreateInstance(Type objtype) in JSON.cs: line 164
at fastJSON.JSON.ParseDictionary(Dictionary`2 d, Dictionary`2 globaltypes, Type type) in JSON.cs: line 471
at fastJSON.JSON.ToObject(String json, Type type) in JSON.cs: line 82
at fastJSON.JSON.ToObject(String json) in JSON.cs: line 75
(I also posted this on CodePlex: [^]. I am not sure where the official forum is.)
|
|
|
|

|
Serializers are generally meant to process "data" types not "meta" types, so unfortunately you can't work with Type as an input.
I prefer this forum than Codeplex as provides a better interface and is easier to work with.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Trying to convert several legacy MVC3 apps to use fastJSON serializer to replace heavy Newtonsoft.Json.JsonConvert.SerializeXmlNode on XMLdocument or Datasets. Our client JavaScript apps require the Ex1 format below for use in jqGrid library. Tried w/ fastJSON (Ex4 & Ex5 output) but can not seem to get the key:value format like Ex1. Is Ex1 serialized output format possible in fastJSON? How? Many thanks for your help!
---------------------------------------------------------------------------
Ex1:Newtonsoft.Json.JsonConvert.SerializeXmlNode
{"person":[{"@id":"1","name":"Alan","url":"http://www.google.com"},{"@id":"2","name":"Louis","url":"http://www.yahoo.com"}]}
---------------------------------------------------------------------------
Ex2:JavaScriptSerializer.Serialize(xmlDoc.InnerXml)
"\u003croot\u003e\u003cperson id=\"1\"\u003e\u003cname\u003eAlan\u003c/name\u003e\u003curl\u003ehttp://www.google.com\u003c/url\u003e\u003c/person\u003e\u003cperson id=\"2\"\u003e\u003cname\u003eLouis\u003c/name\u003e\u003curl\u003ehttp://www.yahoo.com\u003c/url\u003e\u003c/person\u003e\u003c/root\u003e"
---------------------------------------------------------------------------
Ex3:JavaScriptSerializer: DataSetToJSON using dictionary
{"person":[["Alan","http://www.google.com","1"],["Louis","http://www.yahoo.com","2"],null]}
---------------------------------------------------------------------------
Ex4:fastJSON: DataSet to dictionary
{"person":[["Alan","http://www.google.com","1"],["Louis","http://www.yahoo.com","2"],null]}
---------------------------------------------------------------------------
Ex5:fastJSON.JSON.Instance.ToJSON(ds)
{"$schema":{"$type":"fastJSON.DatasetSchema, fastJSON, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Info":["person","name","System.String","person","url","System.String","person","id","System.String"],"Name":"root"},"person":[["Alan","http://www.google.com","1"],["Louis","http://www.yahoo.com","2"]]}
---------------------------------------------------------------------------
|
|
|
|

|
As far as I can see you need
{"property": [ {row in object style key:value with a @id row counter}, {next row} ] }
Which outputs the column names also, while fastJSON outputs in the following style to save space:
{"property": [ [row data only], [next row] ] }
Currently fastJSON does not do this, however you can write your own custom serializer delegate for the property type your need.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hi,
what do you think about to add generic overload(s) of RegisterCustomType method?
something like your overload public T ToObject<T>(string json) for public object ToObject(string json)
I suggest
public void RegisterCustomType<T>(Func<T, string> serializer, Func<string, T> deserializer)
{
RegisterCustomType(typeof(T), (o) => serializer((T)o), (s) => deserializer(s));
}
and/or or (implements both overloads is not a good idea, this cause an ambiguous call when you call method using Lambda Expression)
public void RegisterCustomType<T>(Serialize<T> serializer, Deserialize<T> deserializer)
{
RegisterCustomType(typeof(T), (o) => serializer((T)o), (s) => deserializer(s));
}
adding delegate fields
public delegate string Serialize<T>(T data);
public delegate T Deserialize<T>(string data);
Thank you for sharing your great job
Francesco
modified 19 Sep '12 - 5:01.
|
|
|
|

|
Nice, Francesco!
Will do in the next release soon.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|
|
|

|
Hi Mehdi,
under features you list fastJson as being threadsafe. I wonder if the _usingglobals field doesn't break this.
Unless you specify either true or false globally and never change it
through the Parameters, you can end up with the following scenario:
E.g. _usingglobals is set to false per Parameters.
Deserializing a json string which was serialized with global types and extensions will set it to true in ParseDictionary.
Intermittent serialization on another thread sets it back to false.
Ths initial Deserialization hits the "if (found)" on a sub-object (or even on the initial object after a thread yield), tn contains a number (e.g. "2") but _usingglobals is false again.
Therefore it will *not* look up the globaltypes but instead ultimately call Type.GetType("2") which must fail.
Cheers
Phil
|
|
|
|

|
Global type processing is handled in a class which is created per serialize/deserialize call, so it will not conflict.
Anyway it is being used aggressivly in RaptorDB which is testing it to it's metal.
If you do find any problem in the field let me know and I will fix it.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|
|

|
This is intriguing...
I used the MS singelton pattern, I will change the code and see how it performs.
Thanks Phil!
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Just to be sure: if you use the same kind of fix, you will need to make Parameters static + threadsafe, too. If you like, you can have a look at my fastJson fork on github. I essentially introduced a new static GlobalParameters and changed the Parameters to be an instance property accessing the new static one, for backwards compatbility.
It's funny that this went unnoticed (since 2.0.0 I guess). Probably the combination of sometimes using extensions and sometimes not is not too common.
Anyway, thank you for a really great library
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Smallest, fastest polymorphic JSON serializer (with Silverlight4 and MonoDroid support)
| Type | Article |
| Licence | CPOL |
| First Posted | 19 Feb 2011 |
| Views | 1,554,626 |
| Downloads | 25,736 |
| Bookmarked | 462 times |
|
|