|
|
Comments and Discussions
|
|
 |

|
Thanks Mabakay!
I will look into it and post a fix 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.
|
|
|
|

|
look at the code:
Version oVer = new Version("2012.12.12");
string sNewSer41 = fastJSON.JSON.Instance.ToJSON(oVer);
Version oTest41 = fastJSON.JSON.Instance.ToObject<Version>(sNewSer41);
sNewSer41 parameter is right.
but when deserialize it to Version instance,i find it can't success to deserialize.
Last One Code
|
|
|
|

|
I haven't tested that, if you need it you can write your own custom serializer/deserializer for that type, see the article.
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.
|
|
|
|

|
look at this:
NameValueCollection oCollect = new NameValueCollection(2);
oCollect.Add("key1","value1");
oCollect.Add("key2","value2");
When call the method:
fastJSON.JSON.Instance.ToJSON(oCollect)
it can't get the right result.then i debug the source,finally i find the code in "JsonSerializer.cs" here:
if (obj is Array || obj is IList || obj is ICollection)
WriteArray((IEnumerable)obj);
in fact,NameValueCollection is a key/value collection,although it implement the ICollection interface.
so when NameValueCollection casted IEnumerable interface,it could only serialize NameValueCollection's key.
I think we can add one piece code before that code:
else if (obj is NameValueCollection)
WriteNameValueCollection((NameValueCollection)obj);
the WriteNameValueCollection() method can implement as IDictionary. it that right?
Last One Code
|
|
|
|

|
That could work, I will test and add it in the next release.
Thanks!
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
I noticed that included in the solution there is a Mono for Android project. I also need to run the code on iOS (MonoTouch).
Since the use of reflection on iPhone is limited, I wonder what needs to be done to make fastJSON work without the "Emit" in Refelection.cs (and probably would be called "a little bit less fastJSON" )
I am not too familiar with Reflection Emit myself, but basically creating a slower (non-emit) version of FastCreateInstance, CreateSetField, CreateSetMethod, CreateGetField, CreateGetMethod would do the job ?
Thanks
Gerd
Edit : fastJASON => fastJSON
modified 18-Dec-12 18:07pm.
|
|
|
|

|
It would be possible, although using normal reflection is really slow.
I don't have the resources to test this, so it won't be going on my todo list anytime in the future.
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 just took a very quick initial attempt at replacing the Emit methods in a trivial way. I don't know what I'm doing yet, but 30 out of 34 unit tests pass, (compared to 33 out of 34), so that might be a sign of a good start:
[Update: I got serialization working on my iPhone in Unity3D! Still some exceptions related to casting parameters though.]
http://fastjson.codeplex.com/SourceControl/network/forks/jaredthirsk/fastjsonaot[^]
(I am a MonoTouch user, and a Unity3D user. Unity3D uses an older version of mono that only supports .NET 3.5, so for my fork I set things back to 3.5. Also note you need to pay money to get System.Data.dll support, since it pulls in System.Net.dll, which is a restricted feature for Unity iPhone Basic users like me (got it while it was free).)
(Gotta love git for making forking so easy! And liberal licenses so we can actually use this on iOS devices )
modified 23-Dec-12 10:03am.
|
|
|
|

|
Nice!
Performance?
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.
|
|
|
|

|
Here are some initial numbers: I need to redo the iOS devices to make sure that only the benchmark is running, and no parallel loading is running at the same time.
Another idea I have is to generate the code on a non-AOT machine, save the DLL, and use that on the iOS device.
===================
Macbook Air 1.8Ghz Core i7 - unmodified version
1) Exotic = on
.net version = 4.0.30319.1
press key : (E)xotic
exotic: True
-dataset
Loaded assembly: /Users/jared/Dev/fastjson/consoletest/bin/Release/fastJSON.dll
fastjson serialize 470.98 303.752 309.807 369.708 322.61
fastjson deserializeLoaded assembly: Anonymously Hosted DynamicMethods Assembly [External]
418.443 354.359 427.11 396.857 357.585
+dataset
fastjson serialize 2209.215 2412.338 2232.666 2762.409 2697.409
fastjson deserialize 3508.546 3411.204 3817.756 3442.679 3588.831
2) Exotic = off
.net version = 4.0.30319.1
press key : (E)xotic
exotic: False
-dataset
Loaded assembly: /Users/jared/Dev/fastjson/consoletest/bin/Release/fastJSON.dll
fastjson serialize 261.276 135.076 139.305 136.973 144.693
fastjson deserializeLoaded assembly: Anonymously Hosted DynamicMethods Assembly [External]
184.429 137.761 134.304 134.464 140.832
+dataset
fastjson serialize 134.165 156.669 135.001 146.152 141.247
fastjson deserialize 141.077 145.901 142.572 148.793 142.273
===================
Macbook Air 1.8Ghz Core i7 - AOT-ready version
.net version = 2.0.50727.1433
1) exotic: True, -dataset
fastjson serialize 487.221 378.449 354.955 336.408 334.877
fastjson deserialize [Throws exception: failed to convert parameters]
2) exotic: False,
-dataset
fastjson serialize 209.038 145.409 145.875 140.096 139.527
fastjson deserialize 239.797 212.647 203.514 203.731 203.22
+dataset
fastjson serialize 151.081 139.864 138.69 139.428 142.64
fastjson deserialize 204.956 201.531 203.411 209.698 216.497
===================
iPhone 3GS in Unity3D 3.5.6f4
.net version = 2.0.50727.1433
mono verison = 2.6.5 (tarball)
1) exotic: True, -dataset (dataset not available on this build configuration, requires Unity iOS Advanced license )
fastjson serialize 10422.149 13057.857 10384.186 10362.458 10410.323
fastjson deserialize System.ArgumentException: failed to convert parameters
2) exotic: False
-dataset (dataset not available on this build configuration, requires Unity iOS Advanced license )
fastjson serialize 4790.826 4783.832 4769.139 4922.623 4789.749
fastjson deserialize 4521.374 4526.947 4585.467 4560.347 4510.281
===================
iPad 3rd Generation in Unity3D 3.5.6f4 (Mono)
.net version = 2.0.50727.1433
mono verison = 2.6.5 (tarball)
1) exotic: True, -dataset (dataset not available on this build configuration, requires Unity iOS Advanced license )
fastjson serialize 2810.423 2806.981 2837.854 2809.805 2816.258
fastjson deserialize System.ArgumentException: failed to convert parameters
2) exotic: False, -dataset (dataset not available on this build configuration, requires Unity iOS Advanced license )
fastjson serialize 1290.438 1296.072 1288.941 1293.648 1306.058
fastjson deserialize 1228.635 1224.022 1236.638 1227.458 1230.802
modified 29-Dec-12 22:00pm.
|
|
|
|

|
Hi Mehdi,
I noticed that Code Project lists this article and associated code as being under the CPOL (both on the right navbar and at the end of the article), while Codeplex (and as a result nuget) has fastJSON listed as GPLv2.
This may not be something that you can change here (I'm not too familiar with how it works) but am I right in thinking that it's intended to be under the GPL (ie allowing no commercial use in larger non-opensource works etc) instead of CPOL?
Many thanks!
|
|
|
|

|
The license agreement has always been a pain and I have changed it (on codeplex) a number of times and each time someone is not happy, so I have given up!
You can use fastJSON as you see fit.
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.
|
|
|
|

|
Awesome, thanks!
It really looks like a great piece of software, and I just wanted to make sure that I wouldn't unintentionally be running afoul of the licensing / misusing your hard work before diving in too much.
|
|
|
|

|
"The license agreement has always been a pain and I have changed it (on codeplex) a number of times and each time someone is not happy, so I have given up!
You can use fastJSON as you see fit."
Thanks Mehdi. Tip if you ever want to stop getting these annoying questions about licensing: Some people will still have problems if you leave it at GPL. GPL makes the most people unhappy. BSD and MIT and CPOL and 'Public Domain' makes everybody and their lawyers happy.
|
|
|
|

|
How about apache?
[I changed all my code on Codeplex to apache]
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.
|
|
|
|

|
Apache license is great!
(PS - also, thanks for putting up with all my noise, and also for switching to git.)
modified 22-Dec-12 15:07pm.
|
|
|
|

|
I do get an exception at de line below : It seems as if the object 'v' is not a generic list but a generic dictionary .. any ideas on how to solve this ? Thanks! JSON.cs line 496 else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false) oset = CreateGenericList((List<object>)v, pi.pt, pi.bt, globaltypes);
System.InvalidCastException: Cannot cast from source type to destination type. at fastJSON.JSON.ParseDictionary (System.Collections.Generic.Dictionary`2 d, System.Collections.Generic.Dictionary`2 globaltypes, System.Type type, System.Object input) [0x0026d] in /Users/Gerd/Documents/Documents/Business/Clients/Vendors/fastJSON_v2/fastJSON/JSON.cs:496 at fastJSON.JSON.ToObject (System.String json, System.Type type) [0x00155] in /Users/Gerd/Documents/Documents/Business/Clients/Vendors/fastJSON_v2/fastJSON/JSON.cs:163 at Mobiflow.PersistentAwsS3.LoadJson (System.Type type, System.String path, Mobiflow.LoadJsonFinished finished, System.Object[] parameters) [0x000d3] in /Users/Gerd/Projects/Mobiflow/Mobiflow/Nodes/Management/PersistentAwsS3.cs:389
|
|
|
|

|
Please send me the code you used to get this error.
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 serialize my NodeRootModel, it is written perfectly, but reading back causes the exception
// NodeRootModel public class NodeRootModel : NodeModel { // TODO remove public FilterModel<LocalizedModel> Test { get; set; } } // NodeModel public class NodeModel : SerializableModel { public string SchemaVersion { get; set; } public string SchemaMime { get; set; } public LocalizedModel Name { get; set; } } // SerializableModel public abstract class SerializableModel { // } // FilterModel public class FilterModel<T> : SerializableModel where T : SerializableModel { public T Default { get; set; } } // LocalizedModel public class LocalizedModel : SerializableModel { public string Default { get; set; } public Dictionary<string, string> Localizations { get; set; } }
This written, and is as expected, but reading it back causes an exception { "Test" : { "Default" : { "Default" : "en", "Localizations" : { "en" : "This is a test" } } }, "SchemaVersion" : "1.1", "SchemaMime" : "application/vnd.crt.mobiflow.node.root", "Name" : { "Default" : "en", "Localizations" : { "en" : "Root" } } }
|
|
|
|

|
After some investigation, fastJSON does support generic collections, but <b>not generic nested types</b>?
|
|
|
|

|
JSON.cs line 496 Original code : else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false) oset = CreateGenericList((List<object>)v, pi.pt, pi.bt, globaltypes); Changed to : else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false && v is List<object>) // GZE oset = CreateGenericList((List<object>)v, pi.pt, pi.bt, globaltypes); So CreateGenericList is only called for generic collections and no other generic types. With above changes the code falls through to the point where a class (also generic) is handled. else if (pi.isClass && v is Dictionary<string, object>) oset = ParseDictionary((Dictionary<string, object>)v, globaltypes, pi.pt, pi.getter(o)); Serializing and deserializing of (non-collection) generic types is now handled correctly
|
|
|
|

|
Nice!
I will post this update 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.
|
|
|
|

|
in string : { "Name" : "Ali","Age" : 21, 256} throw Exception in method 'ParseString' : 'Unexpectedly reached end of string' because number of 256 has not name! May be solve it whitout define name?
|
|
|
|

|
This is not a valid json.
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 When I try Deserialize string like : { "Name" : "Ali","Age" : 21} Throw exception from file 'JSON.cs" in line 452 (in method 'ParseDictionary',condition 'type == null'). Where is error?
|
|
|
|

|
Use Parse() when the type information is not in the json (i.e. "$type") or supply the type with ToObject<typehere>(...).
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, I'm looking at using fastJSON for our production system.
Right now I'm stuck on the deserializatiob of a Dictionary>
object. It serializes fine but when I deserialize the inner Dictionary is empty. Any ideas ?
Dictionary<string, Dictionary<string, string>> _allsettings = new Dictionary<string, Dictionary<string, string>>();
_allsettings.Add("test", new Dictionary<string, string>());
_allsettings["test"].Add("fn", "f1");
fastJSON.JSON.Instance.Parameters.UseExtensions = false;
fastJSON.JSON.Instance.Parameters.ShowReadOnlyProperties = true;
string sw = fastJSON.JSON.Instance.ToJSON(theobj);
_allsettings = fastJSON.JSON.Instance.ToObject<Dictionary<string, Dictionary<string, string>>>(sw);
Thanks
Garrett
p.s. this stuff is amazingly quick and works for most my data (except this1)
|
|
|
|

|
Thanks Garrett!
I will check it out.
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,
Impressive work there !
Actually, since you seem to master your serialization stuff pretty well, i was wondering if you could please have a look at a spec proposal i made here
JsonR(aw): Lightweight JSON Protocol Proposal[^]
and maybe consider adding serialization support for it ? It's been really beneficial for us at our company, and I'm sure others will find it interesting too.
There's a GitHub page up, with a small sample page showing off savings.
https://github.com/itechnology/JsonRaw[^]
Thank's for your time,
Robert
|
|
|
|

|
Ah...
As far as I call summarize, JSONP is intended to create smaller packets. My problem with this is :
There are 2 uses for serializers, 1 for data transfer, 2 for data storage, so :
1) For data transfer packet size is important, *but* more important is the fact that both sides must understand the communication, so if you control both sides the you can do what ever you want, but more often than not you cannot control both sides at the same time (versioning etc.) so the packet must contain all the information required.
2) For data storage the problem is even greater since you will have changes and cannot know what the schema was at the time of save so again you must supply all the information for deserializing within the packet.
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 Robert!
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,
First, let me say you have put some excellent work in your fastJSON (de)serializer!
I want to use fastJSON to replace the use of DataContractJsonSerializer in my project and I am wondering if fastJSON will support following features in the near future:
* (de)serialization of *some* private/protected properties (to control access to properties of the object)
* (de)serialization from/to streams (for example: direct deserialization of large (and gzipped) json objects over ethernet)
Thank you!
Regards
Gerd
|
|
|
|

|
Thanks Gerd!
- fastJSON (propably most serializers) don't support private fields/properties, only public ones are supported.
- streams are not supported also, although I have not had any problems working with 17Mb+ json packets in RaptorDB.
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 for your quick response!
DataContractJsonSerializer works with [DataContract] [DataMember] attribute to include properties / fields, even private ones. That way you can add a direct layer of access control on your serializable object. It's also handy that you can name your properties differently in [DataMember(Name = "ID", Order = 1)] etc ...
Anyhow, it was just a suggestion
|
|
|
|

|
Hi Mehdi,
Trying to use it in Monodev project.
The data returned:
{
"access_token":"example",
"token_type":"send",
"expires_in":3430,
"refresh_token":"refresh"
}
Here is the class definition:
[Serializable]
class TokenResponse
{
public String AccessToken
{
get;
set;
}
public String TokenType
{
get;
set;
}
public Int64 ExpiresIn
{
get;
set;
}
public String RefreshToken
{
get;
set;
}
}
If not using type as in :
var newobj = fastJSON.JSON.Instance.ToObject(returnedRawData);
Then getting an exception "Cannot determine type"
If using type as in :
fastJSON.JSON.Instance.Parameters.SerializeNullValues = true;
var newobj = fastJSON.JSON.Instance.ToObject<TokenResponse>(returnedRawData);
The newobj has the corrct names, but values are not populated.
Any ideas what I am missing,
Thanks
F.
|
|
|
|

|
When you are using a plain json string you must supply the object type for the deserialier i.e. ToObject<objecttypehere>(str) also the property names must match exactly.
Yes fastJSON works with mono.
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 Mehdi. But unless I am missing something, here I am supplying the type:
var newobj = fastJSON.JSON.Instance.ToObject<<b>TokenResponse>(returnedRawData);
|
|
|
|

|
The property names don't match : AccessToken- > access_token etc.
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 class with property called PenColors that is of type List<System.Windows.Media.Color>, so I registered a custom deserializer that called ColorConverter.ConvertFromString() to handle conversions for colors. Despite this, when deserializing I would always get an exception from the ChangeType() function in JSON.cs about an invalid cast from 'System.String' to 'System.Windows.Media.Color'. I did some digging and found that it worked fine if I used a simple Color property, but a List<Color>>would fail.
Looking at the code, the CreateGenericList() function calls ChangeType() to add items to the list, but ChangeType() doesn't consider if the type is a registered custom type and ultimately calls Convert.ChangeType() which can't handle Colors, so the conversion fails. I assume this means any custom type in a list would also fail, but I did not test anything other than Color. To fix this, I added the following to ChangeType():
else if (IsTypeRegistered(conversionType))
return CreateCustom((string)value, conversionType);
And now the issue is resolved. I'm not sure if that's the best way to go about it, but it's worked for me so far.
|
|
|
|

|
Thanks!
This will be put in the next release.
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,
i get some Data as String and just want them to deserialize to an object.
In a few cases i get "null" as json-value and the function "fastJSON.JSON.Instance.ToObject(null)" crashes.
Could you please fix this in the next releases? This would be really great, because checking everytime for "null" now isn't very comfortable.
Thank You!
|
|
|
|

|
Missed that in the generic overload, fixed it will post an update soon, thanks.
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.
|
|
|
|

|
No problem, thanks! It's a nice help for me instead of checking around for nulls
|
|
|
|

|
how does the output size compare?
to json.net , servicestack.text...
also what about memory usage while serializing,deserializing?
also is there features that json.net or servicestack.text that fastJson doesn't have?
thanks
|
|
|
|

|
Json is a pretty well defined standard so the sizes should be the same however you might get marginally small output sizes from fastJSON with its $types extension.
fastJSON caches type information for speed but the serialized/deserialize uses no memory (reclaimed by the clr after use).
I can't really say anything about the feature set of other serializers.
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 just checked it,
and the json.net output is smaller than fastJson:
json.net:
[{"Id":123,"Phone":"03-546-4562","Name":"asdas asd asd"},{"Id":321,"Phone":"08-566-5836","Name":"ewrqwer qwer ewrw"}]
fastJson:
[{"$types":{"ClientTester.Testing+MyClass, ClientTester, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null":"1"},"$type":"1","Id":123,"Phone":"03-546-4562","Name":"asdas asd asd"},{"$type":"1","Id":321,"Phone":"08-566-5836","Name":"ewrqwer qwer ewrw"}]
why does it do that, why does it need type information? how can i make it output in the same format of json.net but keep it with fast performance?
thanks
|
|
|
|

|
You can get the same results if you disable fastJSON's extensions.
The type information is for deserializing the exact object model and support for polymorphism.
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.
|
|
|
|

|
also i tried this:
var p = JSON.Instance.Parameters;
p.UseExtensions = false;
p.UsingGlobalTypes = false;
p.ShowReadOnlyProperties = true;
now my class
public class MyClass
{
public int Id { get; set; }
public string Phone { get; set; }
public string Name { get; set; }
}
private readonly MyClass[] cArr = new[] { new MyClass { Id = 123, Name = "asdas asd asd", Phone = "03-546-4562" }, new MyClass { Id = 321, Name = "ewrqwer qwer ewrw", Phone = "08-566-5836" } };
now it does turns into the same json
but i throws exception on deserialization
because the type.IsGenericType is false when you called
GetGenericDefinition on ToObject
invalid operatioexception
at System.RuntimeType.GetGenericTypeDefinition()
at fastJSON.JSON.ToObject(String json, Type type) in D:\UTX\ClientTester\JSON\JSON.cs:line 161
changed it to this
if (o is List<object>)
{
if (type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) // kv format
return RootDictionary(o, type);
if (type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) // deserialize to generic list
return RootList(o, type);
else
return (o as List<object>).ToArray();
}
and the
var o = JSON.Instance.ToObject<object[]>(sj2);
i changed to
var o = JSON.Instance.ToObject<MyClass[]>(sj2);
but now instead of returning me the object[] as MyClass[]
it returns me object[Dictionary<string,object>]
or something like that
why doesn't it just works?
checked the performance compared to json.net
serialization x2 fast
deserialization x6 fast
how can i make it work?
thanks
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Smallest, fastest polymorphic JSON serializer (with Silverlight4 and MonoDroid support)
| Type | Article |
| Licence | CPOL |
| First Posted | 19 Feb 2011 |
| Views | 1,599,299 |
| Downloads | 26,640 |
| Bookmarked | 467 times |
|
|