Sweet Jayson





5.00/5 (2 votes)
Fast, reliable, easy to use, fully json.org compliant, thread safe C# JSON library for server side and desktop operations
- Download library from http://www.nuget.org/packages/Sweet.Jayson
- Download source code from https://github.com/ocdogan/Sweet.Jayson. It is licensed under MIT.
Introduction
There are many .NET JSON libraries you can find on the internet. Some of them say they are small, some say they are fast. Mostly they are right, but what about reliability. When you get in deep, you see that according to your case, they miss something and you cannot succeed with that library or you need to write more and more extensions to manage your specific case. Forget all about these and try Sweet.Jayson
.
Background
It is fast, reliable, easy to use, thread safe and fully json.org compliant. It is designed and coded from ground keeping all these in mind, not after a point in time.
What is Promised?
Sweet.Jayson JSON library supports:
public class CustomBaseType
{
public string Label { get; set; }
public string Ref { get; set; }
public string SHA { get; set; }
public List<string> Items { get; set; }
}
public class CustomType
{
public string State;
public CustomBaseType Base { get; set; }
}
public static class Program
{
public static void Main(params string[] args)
{
var dto = new CustomType() {
{
State = "open"
Base = new CustomBaseType()
{
Label = "technoweenie:master",
Ref = "master",
SHA = "53397635da83a2f4b5e862b5e59cc66f6c39f9c6",
Items = new List<object> { "Dev", "Test", "Prod" }
}
};
var jsonObj =
(Dictionary<string, object>)JaysonConverter.ToJsonObject(dto);
}
}
- .NET 3.5, 4.0, 4.5 & Mono
- Any POCO type serialization/deserialization
- Default .NET types (
DateTime
,DateTimeOffset
,TimeSpan
,Guid
,ArrayList
,Hashtable
,HashSet
…) - Default and custom Generic .NET types (
List<T>
,Dictionary<T,K>
,Stack<T>
,Queue<T>
…) - Concurrent collection types (
ConcurrentBag<T>
,ConcurrentDictionary<T,K>
,
ConcurrentStack<T>
,ConcurrentQueue<T>
) - Any dictionary type that has key type different than
typeof(string)
with special key value pair ($k
,$v
) object (IDictionary<int,decimal>
,IDictionary
,Hashtable
…) DataTable
,DataSet
(also customDataSets
andDataTable
relations inDataSets
)Nullable
types (int?
,DateTime?
…)- Interfaces, both default .NET and also custom interfaces (
IList
,IList<T>
,IMyCustomInterface
…) - Array types (both class and value types) (
int[]
,char[]
,string[]
…) - Byte arrays (
byte[]
) asBase64String
- Multidimensional arrays (
int[,]
) - Jagged arrays (
int[][]
) - Mixed arrays (
int[][,]
andint[,][]
) dynamic
Typesstruct
Types, both on serialization and deserialization- Types without default constructor (e.g.
Tuple
) - Embedding type information with "
$type
" notation for exact type deserialization - Embedding global type information with "
$types
" notation for exact type deserialization and compact output - Including or excluding "
null
" values into/from output (both inProperties
or inLists
separately), - Serializing
Guid
as byte array (byte[]
) - Case sensitive/in-case sensitive property names
{ "state": "open", "base": { "label": "technoweenie:master", "ref": "master", "sha": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6" } }
or:
{ "State": "open", "Base": { "Label": "technoweenie:master", "Ref": "master", "SHA": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6" } }
- Enable/Disable Formatting and beautify output (Pretty print) without performance loss:
{"state"":"open","base"":{"label":"technoweenie:master", "ref"":"master","sha"":"53397635da83a2f4b5e862b5e59cc66f6c39f9c6"}}
or:
{ "state": "open", "base": { "label": "technoweenie:master", "ref": "master", "sha": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6" } }
- Changing types in deserialization using
System.Runtime.Serialization.SerializationBinder
, - Changing
Property
andField
names into any value without using customAttribute
classes byJaysonTypeOverride
:var dto1 = TestClasses.GetTypedContainerDto(); JaysonSerializationSettings jaysonSerializationSettings = JaysonSerializationSettings.DefaultClone(); jaysonSerializationSettings.TypeNames = JaysonTypeNameSerialization.All; jaysonSerializationSettings. AddTypeOverride( new JaysonTypeOverride<TextElementDto>(). IgnoreMember("ElementType"). SetMemberAlias("ElementId", "id")); JaysonDeserializationSettings jaysonDeserializationSettings = JaysonDeserializationSettings.DefaultClone(); jaysonDeserializationSettings. AddTypeOverride( new JaysonTypeOverride<TextElementDto, TextElementDto2>()). AddTypeOverride(new JaysonTypeOverride<TextElementDto2>(). SetMemberAlias("ElementId", "id"). IgnoreMember("ElementType")); string json = JaysonConverter.ToJsonString(dto1, jaysonSerializationSettings); var dto2 = JaysonConverter.ToObject<TypedContainerDto>(json, jaysonDeserializationSettings);
- Changing types in serialization/deserialization using
JaysonTypeOverride
- Ignoring
Field
andProperties
overJaysonTypeOverride
- Including or excluding read-only members (
Field
&Properties
) into/from serialization AnonymousType
serialization/deserialization (deserialization is only possible if the type already exists in the current process)- Custom
Number
(byte
,short
,int
,long
,float
,double
,decimal
,sbyte
,ushort
,uint
,ulong
),
DateTime
,DateTimeOffset
andTimeSpan
formatting in serialization - Various
DateTime
serialization/deserialization formats overJaysonDateFormatType
: Iso8601Local date: "1983-10-25T16:00:30.345+0300" UTC date: "1983-10-25T13:00:30.345Z"
Microsoft
Local date: "/Date(1224043200000+0300)/" UTC date: "/Date(1224043200000)/"
JScript
Local date: new Date(1224043200000+0300) UTC date: new Date(1224043200000)
UnixEpoch
Any long number: 1224043200000
CustomDate
Any date custom date format defined in serialization settings
CustomUnixEpoch
Any custom long number format defined in serialization settings
-
Converting
Decimal
values toDouble
or keep them inDecimal
form -
Enable/Disable
AnonymousTypes
,DynamicObject
andExpandoObject
Types - Enable/Disable Unicode Character Escaping
\u0357
- Sorting
Field
andProperty
names descending - Ignoring
Circular References
or raise exception on Circular Reference - Use
Enum
Type names or numericEnum
values - Maximum Object Depth in deserialization
- Option to work with default types such as
Dictionary<string,object>
orExpandoObject
,
List<object>
,ArrayList
orArray
instead of converting the object to a custom .NET type- Option to parse JSON arrays
[]
conversion betweenList<object>
,ArrayList
orArray
- Option to parse JSON objects
{}
toDictionary<string, object>
orExpandoObject
{ "State": "open", "Base": { "Label": "technoweenie:master", "Ref": "master", "SHA": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6", "Items": [ "Dev", "Test", "Prod" ] } }
will be parsed to:
new Dictionary<string, object> { { "State": "open" }, { "Base": { "Label": "technoweenie:master", "Ref": "master", "SHA": "53397635da83a2f4b5e862b5e59cc66f6c39f9c6", "Items": new List<object> { "Dev", "Test", "Prod" } } } };
- Option to parse JSON arrays
- Custom object creation outside the conversion process using
JaysonObjectActivator
- Converting any .NET object to
Dictionary<string,object>
andList<object>
using
JaysonConverter.ToJsonObject
function
- Object referencing with
$id
and$ref
tags,{ "$type": "ObjectToDict.A, ObjectToDict", "$id": 1, "O2": { "1": { "$type": "System.Decimal, mscorlib", "$value": 2 }, "$id": 2, "a": "b", "true": false, "#self": { "$ref": 2 }, "#list": { "$type": "System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib", "$id": 3, "$values": [ { "$ref": 2 } ] } }, "O1": true, "E1": "EnumB, EnumC", "D2": 23456.78901, "L2": { "$id": 4, "$values": [ 1, null, 2, null ] }, "L1": { "$type": "System.Int64, mscorlib", "$value": 12345678909876544 }, "D4": { "$ref": 2 }, "D1": { "$type": "System.Decimal, mscorlib", "$value": 12345.6789 }, "I1": 123456789 }
-
Enable or disable
KV
mode forDictionary<?,object>
{ "$type": "Sweet.Jayson.Tests.A, Sweet.Jayson.Tests", "D3": { "$type": "System.Collections.Generic.Dictionary`2 [[System.Object, mscorlib],[System.Object, mscorlib]], mscorlib", "1": { "$type": "System.Decimal, mscorlib", "$value": 2 }, "a": "b", "True": false } }
or:
{ "$type": "Sweet.Jayson.Tests.A, Sweet.Jayson.Tests", "D3": { "$type": "System.Collections.Generic.Dictionary`2 [[System.Object, mscorlib],[System.Object, mscorlib]], mscorlib", "$kv": [ { "$k": 1, "$v": { "$type": "System.Decimal, mscorlib", "$value": 2 } }, { "$k": "a", "$v": "b" }, { "$k": true, "$v": false } ] } }
Points of Interest
JSON is a simplified notation for transferring object states. It is simple and easy to use in dynamic languages such as JScript, Pyton, Ruby or any other, but when it comes to use it in statically compiled languages, it is a pain to map and bind to classes.
Do not assume that .NET libraries are supplying you the best of breed out there. Most of the time, they are designed to support generic cases and coded poorly. .NET is a great framework but in each specific case you need it falls short.
My opinion is, you need to try to write your own whenever you need performance and stability, or give a try to a third party library while testing. Also do not assume that every famous third party library is great. Most of the time, they are famous by chance or because they are this first in that area. So, you also need to test them well and accept that they are successful in many cases, but not all. But if you are also in such a case and will try to write your own library, don't forget to be ready for restless days and nights.
This library gets started after testing and testing many third party libraries and .NET's own on JSON serialization and deserialization. When they failed or needed too much effort to success for most of the specific needs, was bored and needed to write a new one which is the new kid in town and wanted to share and let the others not to taste those pain.
Please do not hesitate to get in contact whenever you need help about the library.
History
v1.0.0.0
- 3 May 2015, Initial release
v1.0.0.1
- 6 June 2015, Added support for special types; Stack, Queue and Concurrent lists
v1.0.0.2
- 6 June 2015, Minor fix for list handling, when the last item is
null
or boolean
v1.0.0.3
- 8 June 2015, Performance optimization on GUID serialization
v1.0.0.4
9 June 2015
- Some refactoring
- Sealed some classes
- Error message class implemented
- License header added to JaysonError file
v1.0.0.5
9 June 2015
- Long number serialization fix
AsciiToLower
&AsciiToUpper
fix
v1.0.0.6
10 June 2015
- New tests added
IDictionary<object, object>
Key conversion fixConvertToPrimitive
fix forenum
s
v1.0.0.7
11 June 2015
- Performance improvements
JaysonOrderedDictionary
implemented for member names- Detailed test cases
v1.0.0.8
17 June 2015
- Object referencing support
- Performance optimisation
- Setting for enable/disable
KV
mode forDictionary<?,object>
- Detailed test cases
v1.0.0.9
14 July 2015
System.Runtime.Serialization.ISerializable
interface supportSystem.Type System.Type
serialization supportSystem.Reflection.ConstructorInfo, System.Reflection.MethodInfo
,System.Reflection.PropertyInfo
andSystem.Reflection.FieldInfo
serialization supportSystem.Exception
serialization support- Fix for .Net System.Type.GetType which works different than Mono version
- Detailed test cases