Repository navigation
Commons.Json
Commons.Json is a fast, lightweight .NET JSON library. The library is intended to provide a way that no any configuration or attribute is needed when mapping the JSON string to .NET object and vice versa.
Commons.Json is delivered as a nuget package. You can get the package in nuget.org.
Or in nuget console, you can type following commands and directly install to your project
PM>Install-Package Commons.Json
- Map the object to a JSON string
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Nationality { get; set; }
public string Gender { get; set; }
}
var person = new Person
{
Name = "Joe",
Age = 25,
Nationality = "US",
Gender = "Male"
};
var json = JsonMapper.ToJson(person); // {"Name":"Joe","Age":25,"Nationality":"US","Gender":"Male"}- Map a JSON string to a .NET object
// json string: {"Name":"Joe","Age":25, "Nationality":"US","Gender":"Male"}
var person = JsonMapper.To<Person>(json);- Map a JSON array to list
// json string: [{"Name":"Joe","Age":25, "Nationality":"US","Gender":"Male"}, {"Name":"John", "Age":27, "Nationality":"FR", "Gender":"Male"}, {"Name":"Jane","Age":23, "Nationality":"EN","Gender":"Female"}]
var list = JsonMapper.To<List<Person>>(json);- Map a JSON array to .NET array
// json string : [0, 1, 3, 4, 5, 6]
var array = JsonMapper.To<int[]>(json); // get an int array with value [0, 1, 2, 3, 4, 5, 6]
// json string :[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
var matrix = JsonMapper.To<int[][]>(json); // get an int matrix object.- Map a collection to JSON array. You can map most of collection into a JSON array or a JSON object (for dictionary<string, T>)
var jane = new Person{...};
var john = new Person{...};
var joe = new person{...};
var list = new List<Person>{joe, john, jane};
var json = JsonMapper.ToJson(list);- Map JSON primitives to .NET primtives and string
// json string: 5
var number = JsonMapper.To<int>(json); // number = 5
var anotherNumber = JsonMapper.To<long>(json); // anotherNumber = 5
// json string: 5.6
var floatingNumber = JsonMapper.To<double>(json); // floatingNumber = 5.6
// note: this will fail when json string is 5.6
var wrongNumber = JsonMapper.To<int>(json);
// json string: "a plain string"
var str = JsonMapper.To<string>(json); // str : "a plain string"
// json = true
var b = JsonMapper.To<bool>(json); // b : true- Map .NET primitives and string to JSON
var number = 100;
var json = JsonMapper.ToJson(number); // json string: 100
var floatingNumbe = 5.1274;
var json = JsonMapper.ToJson(floatingNumber); // json string: 5.1274
var str = "the demo string";
var json = JsonMapper.ToJson(str); // json string: "the demo string"- Map an enum
public enum Major
{
CS,
Art,
Politics,
Economics,
Physics,
Chemistry
}
//...
// JSON string: "Art"
var major = JsonMapper.To<Major>(json); // major = Major.Art
// Map the enum to JSON
var json = JsonMapper.ToJson(Major.Physics); // json string: "Physics"-
Map date time
Serialize/deserialize date time in c# is quite slow. To speed up this operation, by default, JsonMapper is to map the date time with json string in "MM/dd/yyyy HH:mm:ss.fff".
-
Map a nullable object
public struct Simple
{
public int Count {get;set;}
public string Name {get;set;}
}
// JSON string: {"Name": "A Simple struct", "Count": 10}
var simple = JsonMapper.To<Simple?>(json);
var count = simple.Value.Count; // count = 10
public class Complex
{
public bool IsValid {get;set;}
public Simple? Simple{get;set;}
}
// JSON string: {"IsValid": true, "Simple": {"Name": "Simple in complex", "Count": 20}}
var comp = JsonMapper.To<Complex>(json);
var count = comp.Simple.Value.Count; // count = 20- Combine those things together...
public class Student
{
public string Name {get;set;}
public int Grade {get;set;}
public Major Major {get;set;}
}
public class School
{
public string Name {get;set;}
public List<Student> Students {get;set;}
}
// json string:
// {"Name": "some university", "Students": [{"Name": "Jane", "Grade": 2, "Major": "Art"}, {"Name": "Jason", "Grade": 3, "Major": "CS"}, {"Name":"Alan", "Grade":3, "Major":"Politics"}]}
var school = JsonMapper.To<School>(json);
var name = school.Name; // Name = "some university"
var students = school.Students;
var name1 = students[0].Name; // name1 = "Jane"
var grade1 = students[0].Grade; // grade1 = 2- Only property with public getters are mapped from object to JSON
public class Employee
{
public class Employee()
{
Gender = "Male";
}
public string Name {get;set;}
public string Gender {get;private set;}
public string Position {private get;set;}
}
//...
var john = new Employee
{
Name = "John",
Position = "Manager"
}
var json = JsonMapper.ToJson(john); // json string: {"Name":"John","Gender":"Male"}- Only property with public setters are mapped from JSON to object
// json string: {"Name": "Jane", "Gender": "Female", "Position": "Director"}
var jane = JsonMapper.To<Employee>(json);
var gender = jane.Gender; // gender = "Male"- When no corresponding property is found on the object, it is ignored
// json string: {"Name": "John", "Position": "Director", "Age": 40}
var john = JsonMapper.To<Employee>(json);
var name = john.Name;
var position = john.Position;
//... The "Age" field is not mapped to the object.- Map context
By default, JsonMapper uses the default map context, which is initialized when JsonMapper is called on the first time.
When you want different mapping behaviors (like map the property into a name other than the property name), a map context is needed in this situation.
Creating a map context may cause unwanted overhead. So it is recommended to use one map context across application or component. It is unwise to always create the map context when map configuration is needed.
Except the map configuration operation, which is usually done in the initialization phase of the application, other operations on map context is thread safe.
- You can tell the mapper to map an object property into a different name
// json string:
// {"School Name": "some university", "Students": [{"Student Name": "Jane", "Grade": 2, "Major": "Art"}, {"Student Name": "Jason", "Grade": 3, "Major": "CS"}, {"Student Name":"Alan", "Grade":3, "Major":"Politics"}]}
var context = JsonMapper.NewContext();
context.For<School>(mapper => mapper.MapProperty(x => x.Name).With("School Name")); // case in-sensitive
context.For<Student>(mapper => mapper.MapProperty(x => x.Name).With("Student Name")); // case in-sensitive
//...
var school = context.To<School>(json);
var schoolName = school.Name; // schoolName = "some university"
var jason = school.Students[1].Name; // jason = "Jason"- And not to map the property
// json string:
// {"School Name": "some university", "Students": [{"Student Name": "Jane", "Grade": 2, "Major": "Art"}, {"Student Name": "Jason", "Grade": 3, "Major": "CS"}, {"Student Name":"Alan", "Grade":3, "Major":"Politics"}]}
var context = JsonMapper.NewContext();
context.For<School>(mapper => mapper.MapProperty(x => x.Name).With("School Name")); // case in-sensitive
context.For<Student>(mapper => mapper.MapProperty(x => x.Name).With("Student Name").Not.MapProperty(x => x.Grade)); // case in-sensitive
//...
var school = context.To<Employee>(json);
var jasonGrade = school.Students[1].Grade; // jasonGrade = 0. The value of the property that is not mapped is default(T)- If the object does not have a default conctructor or you want to specify the constructor
public class Book
{
public Book(string category)
{
Category = category;
}
public string Name {get;set;}
public string Aurthor {get;set;}
public string Category {get;private set;}
}
// json string: {"Name":"The Republic", "Author": "Plato"}
var context = JsonMapper.NewContext();
context.For<Book>(mapper => mapper.ConstructWith(() => new Book("Philosophy")));
var book = context.To<Book>(json);
var name = book.Name; // name = "The Republic"
var author = book.Author; // author = "Plato"
var category = book.Category; // category = "Philosophy"- Manually convert JSON string to an object
public class Strange
{
public string StrangeProp1 {get;set;}
public string StrangeProp2 {get;set;}
public string StrangeProp3 {get;set;}
}
public class Nice
{
public string Nice1 {get;set;}
public Strange TheStranger {get;set;}
}
// json string: { "Nice1": "n1", "TheStranger": { "Normal1": "Value1", "Normal2": "Value2", "Normal3": "Value3"}
var context = JsonMapper.NewContext();
context.For<Strange>(mapper => mapper.ConstructWith(x =>
{
var jsonObj = (JObect)x;
var strange = new Strange();
strange.StrangeProp1 = jsonObj.GetString("Normal1");
strange.StrangeProp2 = jsonObj.GetString("Normal2");
strange.StrangeProp3 = jsonObj.GetString("Normal3");
return strange;
}));
var nice = context.To<Nice>(json);
var prop1 = nice.TheStranger.StrangeProp1; // prop1 = "Value1"
var prop2 = nice.TheStranger.StrangeProp2; // prop2 = "Value2"
var prop3 = nice.TheStranger.StrangeProp3; // prop3 = "Value3"
- Convert JSON into an interface
public interface IAwesome
{
string WhyIamAwesome {get;set;}
}
public class Wonder : IAwesome
{
public string WhyIamAwesome {get;set;}
}
public class Destination
{
public string Place {get;set;}
public IAwesome Awesome {get;set;}
}
var context = JsonMapper.NewContext();
context.For<IAwesome>(mapper => mapper.ConstructWith(() => new Wonder()));
//JSON string: {"Place": "Giza", "Awesome": {"WhyIamAwesome": "Astonishing ancient pyramids"}}
var thing = context.To<Destination>(json);
var reason = thing.Awesome.WhyIamAwesome; // reason = "Astonishing ancient pyramids"- Manually construct an interface for multiple implementations
public class Park : IAwesome
{
public string WhyIamAwesome {get;set;}
pubilc string BestSeason {get;set;}
}
public class Beach : IAwesome
{
public string WhyIamAwesome {get;set;}
public string Event {get;set;}
}
var context = JsonMapper.NewContext();
context.For<IAwesome>(mapper => mapper.ConstructWith(x =>
{
var jsonObj = x as JObject;
IAwesome awe;
if (jsonObj.ContainsKey("BestSeason"))
{
var park = new Park();
park.BestSeason = jsonObj.GetString("BestSeason");
awe = park;
}
else if (jsonObj.ContainsKey("Event"))
{
var beach = new Beach();
beach.Event = jsonObj.GetString("Event");
awe = beach;
}
else
{
throw new ArgumentException();
}
awe.WhyIamAwesome = jsonObj.GetString("WhyIamAwesome");
return awe;
}));
// JSON string: [{"Place": "Yellow Stone", "Awesome": {"WhyIamAwesome": "beautiful scenery", "BestSeason": "Autumn"}},{"Place": "Honululu", "Awesome": {"WhyIamAwesome": "Beautiful beach", "Event": "Surfing"}}]
var places = context.To<List<Destination>>(json);
var park = (Park)places[0].Awesome;
var bestSeason = park.BestSeason; // bestSeason = "Autumn"
var beach = (Beach)places[1].Awesome;
var event = beach.Event; // event = "Surfing"- Use a specific date time format
When the default date time format is not intended, a specific format can be specified on the map context.
public class Baby
{
public string Name {get;set;}
public DateTime Dob {get;set;}
}
// json string: {"Name":"Cutie", "Dob":"04/11/2016"}
var cutie = JsonMapper.NewContext().UseDateFormat("MM/dd/yyyy").To<Baby>(json);
var birthday = cutie.Dob; // birthday = 04/11/2016 00:00:00- And use the default date time format for the current culture
When serialize or deserialize directly through JsonMapper instead of map context, the default date time format is always used.
var baby = JsonMapper.To<Baby>(json);
//...- Manually convert from object to JSON
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Nationality { get; set; }
public string Gender { get; set; }
}
var person = new Person
{
Name = "Joe",
Age = 25,
Nationality = "US",
Gender = "Male"
};
var json = JsonMapper.ConvertToJson(person, p =>
{
var jsonObj = new JObject();
jsonObj.SetString("Person Name", p.Name);
jsonObj.SetInt32("Person Age", p.Age);
jsonObj.SetString("Nation", p.Nationality);
jsonObj.SetString("Sex", p.Gender);
return jsonObj;
});
// json string: {"Person Name": "Joe", "Person Age": 25, "Nation": "US", "Sex":"Male"}- Manually convert from JSON to object
// json string: {"Person Name": "Joe", "Person Age": 25, "Nation": "US", "Sex":"Male"}
var person = JsonMapper.ConvertTo<Person>(json, jsonValue =>
{
var jsonObj = jsonValue as JObject;
var p = new Person();
p.Name = jsonObj.GetString("Person Name");
p.Age = jsonObj.GetInt32("Person Age");
p.Nationality = jsonObj.GetString("Nation");
p.Gender = jsonObj.GetString("Sex");
return p;
});
var name = person.Name; // name = "Joe"
var age = person.Age; // age = 25
var nation = person.Nationality; // nation = "US"
var gender = person.Gender; // gender = "Male"- Work with dynamic JSON object
// json string: {"Name":"A Storm of Swords", "Series":"A Song of Ice and Fire", "Author": "G.R.R.Martin", "Language": "English"}
dynamic novel = JsonMapper.Parse(json);
string name = novel.Name; // name = "A Storm of Swords"
string series = novel.Series; // series = "A Song of Ice and Fire"
string author = novel.Author; // author = "G.R.R.Matin"
string lang = novel.Language; // lang = "English"- Dynamic JSON array
// json string: [{"Name":"A Clash of Kings", "Series":"A Song of Ice and Fire", "Author": "G.R.R.Martin", "Language": "English"}, {"Name":"A Storm of Swords", "Series":"A Song of Ice and Fire", "Author": "G.R.R.Martin", "Language": "English"}]
dynamic novels = JsonMapper.Parse(json);
string clash = novels[0].Name; // clash = "A Clash of Kings"
string storm = novels[1].Name; // storm = "A Storm of Swords"