|
|
Comments and Discussions
|
|
 |

|
wow! Another excellent article! Impressive work Mehdi
|
|
|
|

|
I already voted this code 5 because it is soooo fast! One thing I noticed:
This code:
else if (obj is string || obj is char)
WriteString((string)obj);
will not work on a char type.
Please change to something like:
else if (obj is string || obj is char)
WriteString(obj.ToString());
You can see this in action if you change the sample code to:
var q = new { Name = "asassa", MiddleInitial = 'G', Address = "asadasd", Age = 12 };
Thanks again for sharing this... it really is fast.
|
|
|
|

|
Blazing fast! I have a small array of objects that takes:
27866 ms in JavaScriptConvert.SerializeObject
22667 ms in JavaScriptSerializer.Serialize
and .2058 ms in fastJSON
Yes, that is 100K times faster!
|
|
|
|
|

|
Could you post a small sample code that shows us how to use your fastJSON in a WCF service?
I think I'm not the only one interested in it.
|
|
|
|

|
Hello,
Is fastJSON able to report where a json file is not correctly formated ?
This would be usefull:
- the line number
- the character index
- the error type
Thanks !
|
|
|
|
|

|
Formatter.cs, line 59 says
if (!IsEscaped(output, i))
It should be
if (!IsEscaped(output, output.Length))
because it needs to look for an escaped quote relative to the OUTPUT
buffer, not the INPUT string.
|
|
|
|

|
I have created a object with a List that contains objects. Serialization is ok, when I deserialize immediately also ok. But when I deserialize the json text from a file, I get a NullreferenceException on _Params in line 526 in JSON.cs file. my code:
using System.Collections.Generic;
using System.IO;
using fastJSON;
namespace consoletest
{
public class Program
{
public static void Main(string[] args)
{
const string filename = "Zoo.json";
#if NOLOADTEST
Zoo gaiapark = Zoo.MakeZoo();
Zoo.SaveZoo(gaiapark, filename);
#endif
Zoo artis = Zoo.LoadZoo(filename);
}
}
public class Animal
{
public string Name { get; set; }
}
public class Cat : Animal
{
}
public class Dog : Animal
{
}
public class Zoo
{
public List<Animal> Animals { get; set; }
public static Zoo MakeZoo()
{
Zoo zoo = new Zoo();
zoo.Animals = new List<Animal>();
Animal cat = new Cat();
cat.Name = "Aramis";
zoo.Animals.Add(cat);
Animal dog = new Dog();
dog.Name = "Porthos";
zoo.Animals.Add(dog);
dog = new Dog();
dog.Name = "Athos";
zoo.Animals.Add(dog);
return zoo;
}
public static void SaveZoo(Zoo zoo, string filename)
{
string jsonStr = JSON.Instance.ToJSON(zoo);
File.WriteAllText(filename, jsonStr);
}
public static Zoo LoadZoo(string filename)
{
string jsonStr = File.ReadAllText(filename);
Zoo zoo = JSON.Instance.ToObject<Zoo>(jsonStr);
return zoo;
}
}
}
modified 16 Jun '12 - 11:10.
|
|
|
|

|
I have the following problem, sample code:
Public Structure GeoPoint
Public Lat As Integer
Public Lon As Integer
Public Sub New(ByVal lat As Integer, ByVal lon As Integer)
Me.Lat = lat
Me.Lon = lon
End Sub
End Structure
Public Class ItemsC
Public i As Integer
Public name As String
Public Property Points As New List(Of GeoPoint)
End Class
Dim Points As New List(Of GeoPoint)
Private Sub TestCode()
With Points
.Add(New GeoPoint(-38050940, -57554840))
.Add(New GeoPoint(-38054630, -57549710))
.Add(New GeoPoint(-38053280, -57548118))
.Add(New GeoPoint(-38053445, -57547270))
.Add(New GeoPoint(-38052632, -57549008))
.Add(New GeoPoint(-38053348, -57549767))
End With
Dim itc As New ItemsC
itc.name = "TestName"
itc.i = 4
fastJSON.JSON.Instance.Parameters.EnableAnonymousTypes = True
For Each t In Points
With itc
.Points.Add(t)
End With
Next
Dim str = fastJSON.JSON.Instance.ToJSON(itc)
str = fastJSON.JSON.Instance.Beautify(str)
Stop
End Sub
Calling the method "TestCode()" the result is as following (Notice the "Lat" field):
{
"Points" : [
{
"Lat" : 94250684,
"Lon" : -38050940
},
{
"Lat" : 94250684,
"Lon" : -38054630
},
{
"Lat" : 94250684,
"Lon" : -38053280
},
{
"Lat" : 94250684,
"Lon" : -38053445
},
{
"Lat" : 94250684,
"Lon" : -38052632
},
{
"Lat" : 94250684,
"Lon" : -38053348
}
],
"i" : 4,
"name" : "TestName"
}
if I replace the structure with a Class like this:
Public Class GeoPoint
Public Lat As Integer
Public Lon As Integer
Public Sub New(ByVal lat As Integer, ByVal lon As Integer)
Me.Lat = lat
Me.Lon = lon
End Sub
End Class
The result string is correct!
I'm using VS2010, with VB.net and target .net framework 3.5.
Thanks in advance.
|
|
|
|

|
Hi, i got a property which looks like this:
public List<IFoobar> MyList { get; private set; }
when deserializing, a NullReferenceException will occur in
> RaptorDB.Common.DLL!fastJSON.JSON.ParseDictionary(System.Collections.Generic.Dictionary d, System.Collections.Generic.Dictionary globaltypes, System.Type type, object input) Line 629 + 0x12 bytes C#
I think you should replace
if (pi.CanWrite)
pi.setter(o, oset);
by
if (pi.setter != null)
pi.setter(o, oset);
or set the pi.CanWrite property accordingly.
ps: I'm using the version from RaptorDB_doc_v1.4.zip.
|
|
|
|

|
A very usefull source code share. I definitly try it in some projects.
|
|
|
|

|
Can I use FillObject() to populate a dataset?
Is it possible to deserialise JSON (with the schema that has been included in the serialisation) directly into a new dataset using the included schema?
Thanks
|
|
|
|
|

|
Reproduce Case:
1) Initialize a static Json object from fastJSON.JSON.Instance.
2) Prepare the Json string .
3) Invoke the ToObject<T> to convert string to one defined class.
4) Exception occurs at ParseDictionary().
Root Cause:
In mentioned scenario, the parameter can not be assigned to Json object.
So the _params is null.
But ParseDirectory needs to use it like below
if (_params.IgnoreCaseOnDeserialize) name = name.ToLower();
modified 19 May '12 - 9:44.
|
|
|
|

|
Hi Mehdi,
Seems function "object ToObject(string json)" didn't work list,could you double check it?
BTW: 5 from me
Jack
|
|
|
|

|
Maybe it is JSONParameters.
|
|
|
|

|
Love your work - very fast and efficient!
I am having trouble deserializing a dataset - any known limitations on this?
Have followed your example in the consoletest project (which I noticed was commented out).
Thanks
|
|
|
|

|
I like your coding style.
|
|
|
|

|
Very useful & good comparison! Thanx!@
|
|
|
|

|
Good try, but the approach isn't as flexible as it should be. See my earlier post "Not Attributed".
|
|
|
|

|
Looks like the file is not available from CodeProject.
Got it from CodePlex, though.
modified 10 May '12 - 16:32.
|
|
|
|

|
What is the main objective of your project?
- to widen the scope of JSON serialization?
- to offer faster JSON operations?
Back a while when I thought of it the first time, I was thinking of using an attributed extender to JSON, when you have the base class, which has attributes to be used in a derived class. This way you can specify which attributes of an object you want to be automatically serialized into JSON, if you don't want the whole object. In your implementation, if I understand correctly, the entire object is serialized always, which is often unneeded.
Say, you have a class that implements some business logic, preparing parameters to be later serialized into JSON and then later returned in response to a query. If I can serialize only an entire object, this means I have to create another class to wrap up all the properties for serialization, and then use it as container within my business class. Well, this is not elegant at all, especially if you consider there can be a derived class with extra properties that needs to be serialized along, then such concept simply falls apart.
You need to be able to attribute explicitly the properties to be serialized, or it will create problems.
Any thoughts on that?
|
|
|
|
|

|
Hi again Mehdi!
I've got another possible new suggestion for your great project
I usually use fastJSON within my own classes implementing two methods:
1. ToJSON() which only calls fastJSON.Instance.ToJSON(this)
2. CreateFromJSON(string input), a constructor factory just returning (MyOwnClass)fastJSON.Instance.ToObject(input)
That's nice for nearly all cases, but, now, I'm working with a framework where I can't use constructor factories as it automatically create instances of my own classes BUT only using the default parameterless constructor.
So, if I want to continue to use fastJSON, I always must create a default constructor that creates an instance of that class and maps each property:
class MyOwnClass
{
int a;
int b;
public MyOwnClass()
{
string json=GetMyStringFromSomeWhere();
MyOwnClass dummy=(MyOwnClass)fastJSON.Instance.ToObject(json);
this.a=dummy.a;
this.b=dummy.b;
}
}
Before to go to use reflection to iterate throught all properties or to dive and customize your code, I'd like to comment it to you.
I think you could add a new feature to the project to load an existing object instead of creating it... i.e.: fastJSON.Instance.LoadObject(this);
It's a long time ago when I revised your job and I didn't remember exactly how you did it, but, maybe it will be as easy as to change the first iteration in the recursive call, to only set properties without creating the main instance... won't it?
How it sounds to you?
Best regards,
Marc
|
|
|
|

|
Unfortunately, this implementation is limited by the max size of StringBuilder. I was trying to serialize a long list and keep running into StackTrace " at System.String.GetStringForStringBuilder(String value, Int32 startIndex, Int32 length, Int32 capacity)\r\n at System.Text.StringBuilder.GetNewString(String currentString, Int32 requiredLength)\r\n at System.Text.StringBuilder.Append(String value)\r\n at fastJSON.JSONSerializer.WriteValue(Object obj)\r\n at fastJSON.JSONSerializer.WritePair(String name, Object value)\r\n at fastJSON.JSONSerializer.WriteObject(Object obj)\r\n at fastJSON.JSONSerializer.WriteValue(Object obj)\r\n at fastJSON.JSONSerializer.WriteArray(IEnumerable array)\r\n at fastJSON.JSONSerializer.WriteValue(Object obj)\r\n at fastJSON.JSONSerializer.ConvertToJSON(Object obj)\r\n at fastJSON.JSON.ToJSON(Object obj, Boolean enableSerializerExtensions, Boolean enableFastGuid, Boolean enableOptimizedDatasetSchema, Boolean serializeNullValues)\r\n at fastJSON.JSON.ToJSON(Object obj)\r\n
|
|
|
|

|
System.MissingMethodException: Method not found: 'Void System.Reflection.Emit.DynamicMethod..ctor(System.String, System.Type, System.Type[])'.
at fastJSON.JSON.CreateGetMethod(PropertyInfo propertyInfo)
at fastJSON.JSON.GetGetters(Type type)
at fastJSON.JSONSerializer.WriteObject(Object obj)
at fastJSON.JSONSerializer.WriteValue(Object obj)
at fastJSON.JSONSerializer.ConvertToJSON(Object obj)
|
|
|
|

|
I love this post. I refer peers who are new to JSON to it all the time.
I'm wondering, could fastJSON be use to directly convert XML files without a "known" schema? I'm thinking about writing a XmlToJSON app so that folks can import XML to MongoDB.
Thoughts?
Thanks again for a great article.
-m
|
|
|
|

|
Just started to have a look at the code and in the SafeDictionary class I saw that you have a lock around the Add(...) method, but the TryGetValue, operator[] and GetEnumerator are not protected.
This code is incorrect if used in a multi-threaded environment.
Have fun,
Paul Westcott.
|
|
|
|

|
Like a previous poster, I also cannot deserialize a string array.
|
|
|
|

|
Example code
public class Test
{
public int? A { get; set; }
public int? B { get; set; }
}
var x = new Test { A = 0 };
var res = JSON.Instance.ToJSON(x, false, true, true, false);
Result is {"A":0,}
The MVC 3 JsonSerializer throws a 500 error when it gets json like that. jsonlint[^] also reports it as invalid json.
Author of Plane9 the sound sensitive screensaver and music visualizer.
|
|
|
|

|
I would like to know how cyclic graphs are handled.
Nothing is imposible if you believe in it.
http://dotnetcaffe.blogspot.com/
|
|
|
|

|
Hello.
I'm using fastJson from a while and I'm really pleased from it!!
Now I need to send json data from my server (written in C#, adopting fastJson as library to serialize/deserialize) to a Java client and viceversa.
In this scenario things are more complicated, as the Java client creates a JSON payload without the "$types" information.
How may I cope with this issue? Is there a port of fastJson in Java language?
Hope to listen to you as sson as possbile!
Thank you very much.
Cghersi
|
|
|
|

|
Nice have 5 from me. Could you kindly include a demo on how to use raptordb.
Thanks
|
|
|
|

|
Thank you ... Good job ... I needed a VB version so I converted some of the code to VB.NET ... The code can be found in the Issue tracker at fastjson.codeplex.com
|
|
|
|

|
I wanted to use this code to deserialize an array of objects and as written it just returns null.
The code I was attempting to use was:
string jsonstring = "[{ ...... }, {.....}]"; // edited for brevity
MyObjectType[] ar = fastJSON.JSON.Instance.ToObject( jsonstring );
This results in null because the intermediate form of the parsed data is an ArrayList but the ToObject method is expecting the input to always be an object not an array. The result is 'as' casted to a Dictionary which causes a null to be passed to ParseDictionary(). If a hard cast was used I guess it would throw an exception instead but currently just fails without errors. I have made the following modification to the ToObject(string, type) method in JSON.cs to make my use case work.
public object ToObject( string json, Type type )
{
object jsonobj = new JsonParser( json ).Decode();
if( jsonobj == null )
{
return null;
}
if( type != null && type.IsArray )
{
if( jsonobj is ArrayList )
{
return CreateArray( (ArrayList)jsonobj, type, type.GetElementType(), null );
}
else
{
throw new Exception( "Conversion to array type was requested but the JSON input was not parsed to an array" );
}
}
else
{
return ParseDictionary( (Dictionary<string, object>)jsonobj, null, type );
}
}
|
|
|
|

|
fastJSON.JSON.Instance.ToObject("[\"test\",\"string\"]") returns null.
Am I calling this incorrectly?
|
|
|
|

|
I'm a bit new to JSON, I was wondering what steps I should take to begin parsing something that looks like:
{
"POLINFO" : {
"NM" : "RTN",
"ID" : "",
"HC" : null
},
"MIR" : null,
"IG" : [{
"T" : null,
"F" : "a$",
"S" : "a$"
"TP" : "a$",
}, {
"T" : null,
"F" : "a$",
"S" : "a$"
"TP" : "a$",
}, {
"T" : null,
"F" : "a$",
"S" : "a$"
"TP" : "a$",
}, {
"T" : null,
"F" : "a$",
"S" : "a$"
"TP" : "a$",
}, {
"T" : null,
"F" : "a$",
"S" : "a$"
"TP" : "a$",
}, {
"T" : null,
"F" : "a$",
"S" : "a$"
"TP" : "a$",
}
],
"SI" : {
"NST" : "1",
"SST" : null
},
"ISO" : false,
"A2C" : "",
"A2CBT" : "",
"CI" : {
"CI" : "",
"PN" : "",
"PID" : "",
"SOURCE" : ""
},
}
Anything can help. I created a class that mimics the data entries so that I can enter it into the overloaded Quote: fastJSON.JSON.Instance.ToObject(Document, typeof(JSONTEST));
but I think I need to define a dictionary to map variables with the stated values still. I don't know how to do that though. Thanks for your time.
|
|
|
|

|
Thanks for sharing
|
|
|
|

|
I have a problem with deserialization. My code is
var obj = new Dictionary<string, string>() { { "Process", "ProcName" } };
string json = JSON.Instance.ToJSON(obj);
var obj2 = JSON.Instance.Parse(json);
And last string throws an exception "Could not find token at index 15".
When this option is used
JSON.Instance.UseSerializerExtension = false;
all works fine.
And second question: why you made serializer as singleton? In some cases I would like to change serialization options (only for one specific case), so making JSON constuctor public would be great.
|
|
|
|

|
Hi Mehdi, I'm approaching your library for the first time.
I have the following issue:
abstract class A { string MyProp { get; set; } }
class Aimpl : A { ... }
class Program
{
public void main()
{
A temp = new Aimpl();
temp.MyProp = "my content";
Console.WriteLine(fastJSON.JSON.Instance.ToJSON(temp));
}
}
The output json makes reference to the Aimpl class (something like {"$types":{"MyNameSpace.Aimpl, ...":"1"},"$type":"1", "MyProp":"my content"}), but I need to have a json referencing A class (something like {"$types":{"MyNameSpace.A, ...":"1"},"$type":"1", "MyProp":"my content"}) because I need to pass this json to a client where the Aimpl class is not available, but only the A class...
Is there a way to obtain the reference to the A class in the resulting json string?
Thank you very much for your support, and most of all for your terrific library!
Best
cghersi
|
|
|
|

|
I have a class that has 2 objects in it, call it MYdocument. MyData _sd which only has a bunch of Strings and Booleans, and _history that was a Stack. At first i was able to serialize and deserialize the object, but when I started using the _history object it started failing, in JSON.ParseDictionary(Dictionary d) on the line [setter(o, oset);]. I figured it was the Stack object and changed it to a Dictionary containing a version string as the key and a JSON of the _sd object.
String json = fastJSON.JSON.Instance.ToJSON(_sd); is returning an incomplete JSON object ->
"{\"$type\":\"MYdocument+MyData, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\",}"
_sd is just an object with private String and Boolean values, approx 30 of them.
When it was working, I noticed that the strings being generated don't seem to be staying true to the JSON format, a section of the value pairs:
"Title":"David""Version":"v.1.0.4""Date":"11/25/2011 10:11:07 AM""Group":"DevTeam""BillingCode":"lkj""Liaison":"lkj""Priority":"Critical""Timeframe":"lkjlkj""Summary":"lkj""Features":"lkj"
none of the key:value pairs are comma separated as I think it's stated in the JSON Specification. I plan on using the JSON objects with other C++, JavaScript, and Object C projects and am worried they won't deserialize properly.
Also all of the items are using the property get/set names, and not the actual varible names ex: _applicationTitle is the actual variable name in the class, and Title is the property get/set name.
|
|
|
|

|
Hi! I'll probably make a change from using XML to JSON in my metadata after knowing about your serializer. It's simply great!
After some tests, I've got a suggest for you: I'm using a lot of polymorphism in my classes, so, I need to use always the type notation serialization. Then, I've got a text where a huge part of it is composed of some type/assembly sentences repeated again and again along all the file, and I think there could be a simply way to compress all that data in a more efficient way.
I saw you've used a Dictionary to buffer all the types, both in serialize and when parsing... What do you thing about to save that dictionary as something like a header in the file and use only a key in every object? also, a lot of the types uses the same assembly, same version, same token, so, this header could also be writed in cascade and be very short.
I'm tempted to modify the code by myself, but I'm sure you'll do it much better... it's your code!
Thanks for your great code.
Best regards,
Marc Baye
|
|
|
|

|
Nice Article
|
|
|
|
|

|
It appears that it isn't possible to serialize anything containing self/mutual references. Any plans on implementing this? It would have to be an extension using an $id for every reference type object, and a $ref value when an object reoccurs.
|
|
|
|

|
I have a Dictionary.
The second string is a serialized Dictionary.
This serializes as:
{
"NetworkShell.ViewModels.ShellModel":"
[
{"k":"Height","v":680},
{"k":"Top","v":327},
{"k":"Width","v":1010},
{"k":"Left","v":1754}
]",
"NetworkShell.ViewModels.LoggerModel":"
[
{"k":"MinimumLevel","v":"Error"}
]"
}
When trying to dezsialize it in the first step to Dictionary, I get a run time error.
I think it is because the serialized string is not escaped?
|
|
|
|

|
The line public bool isCustomType; in JSON.cs (very last version) needs to be removed — it is unused and causes warning. Please do it.
—SA
Sergey A Kryukov
|
|
|
|

|
@@ -31,6 +31,7 @@ public bool SerializeNullValues = true; public bool UseUTCDateTime = false; public bool ShowReadOnlyProperties = false; + public bool IgnoreCase = false; public string ToJSON(object obj) { @@ -214,7 +215,7 @@ d.CanWrite = p.CanWrite; d.setter = CreateSetMethod(p); d.getter = CreateGetMethod(p); - sd.Add(p.Name, d); + sd.Add(IgnoreCase ? p.Name.Lower() : p.Name, d); } FieldInfo[] fi = type.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo f in fi) @@ -222,7 +223,7 @@ myPropInfo d = CreateMyProp(f.FieldType, f.Name); d.setter = CreateSetField(type, f); d.getter = CreateGetField(type, f); - sd.Add(f.Name, d); + sd.Add(IgnoreCase ? f.Name.ToLower() : f.Name, d); } _propertycache.Add(typename, sd); @@ -458,7 +459,7 @@ continue; } myPropInfo pi; - if (props.TryGetValue(name, out pi) == false) + if (props.TryGetValue(IgnoreCase ? name.ToLower() : name, out pi) == false) continue; if (pi.filled == true) {
|
|
|
|

|
It works perfectly and is the only (de)serializer that can successfully serialize complex and "exotic" types like Dictionary. It can also be used in applications for WP7, so I'll use it there, too.
|
|
|
|

|
It seems that Silverlight 5.0 is stricter about using the Array.CreateInstance as it really shouldn't have worked, due to Silverlight not supporting many of the generic arrays, etc.
Thus when using FastJSON in Silverlight 5.0 you need to update the CreateArray function to something like this:
private object CreateArray(List<object> data, Type pt, Type bt) {
var listType = typeof(List<>).MakeGenericType(new[] { bt });
var listOfCustom = Activator.CreateInstance(listType);
foreach (object ob in data) {
if (ob is IDictionary)
listType.GetMethod("Add").Invoke(listOfCustom, new[] { ParseDictionary((Dictionary<string, object>)ob, bt) });
else
listType.GetMethod("Add").Invoke(listOfCustom, new[] { ChangeType(ob, bt) });
}
return(listType.GetMethod("ToArray").Invoke(listOfCustom, null ));
}
|
|
|
|
 |
|
|
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,556,951 |
| Downloads | 25,758 |
| Bookmarked | 462 times |
|
|