private JsonArray SerializeDictionary(IDictionary dictionary) { //Prepare JsonArray jsonArray = new JsonArray(); //Check if (dictionary == null) { throw new ArgumentNullException(nameof(dictionary)); } //Loop foreach (object key in dictionary.Keys) { //Serialize key JsonObject keyObject = Serialize(key); //Serialize value JsonObject valueObject = Serialize(dictionary[key]); //Create new collection JsonElementCollection jsonKeyValuePair = new JsonElementCollection(); jsonKeyValuePair.Add(new JsonElement() { Name = "key", Value = keyObject }); jsonKeyValuePair.Add(new JsonElement() { Name = "value", Value = valueObject }); //Add jsonArray.Elements.Add(jsonKeyValuePair); } //Return return(jsonArray); }
private void DeserializeObject(object instance, Type objectType, JsonObject jsonObject) { //Check JsonElementCollection jsonCollection = new JsonElementCollection(); if (jsonObject is JsonElementCollection) { jsonCollection = (JsonElementCollection)jsonObject; } //Loop through publicly exposed writable properties foreach (var propertyInfo in objectType.GetProperties()) { //Prepare string name = propertyInfo.Name; //Check attributes JsonSerializeAttribute attribute = propertyInfo.GetCustomAttribute <JsonSerializeAttribute>(); if (attribute != null) { if (!string.IsNullOrEmpty(attribute.Name)) { name = attribute.Name; } } //Check if writable if (propertyInfo.CanWrite) { //Set property value if (jsonCollection.Contains(name)) { propertyInfo.SetValue(instance, GetValue(propertyInfo.PropertyType, jsonCollection[name].Value)); } } //Check if is not value type and is currently not null. else if (!propertyInfo.PropertyType.IsValueType && propertyInfo.GetValue(instance) != null) { //Get instance object value = propertyInfo.GetValue(instance); Type propertyType = propertyInfo.PropertyType; //Check if value implements IDictionary if (propertyType.GetInterface(typeof(IDictionary <,>).Name) != null && value is IDictionary dictionary) { //Prepare Type dictionaryType = propertyType.GetInterface(typeof(IDictionary <,>).FullName); Type keyType = dictionaryType.GetGenericArguments()[0]; Type valueType = dictionaryType.GetGenericArguments()[1]; MethodInfo addMethod = dictionaryType.GetMethod("Add"); JsonObject jsonValue = jsonCollection[name].Value; //Loop through key value pairs if (jsonValue is JsonObjectCollection jsonObjects) { foreach (JsonObject jsonKeyValuePair in jsonObjects) { //Check if object is a JSON element collection if (jsonKeyValuePair is JsonElementCollection jsonKeyValuePairCollection) { //Get key and value from the JSON key value pair object keyValuePairKey = GetValue(keyType, jsonKeyValuePairCollection["key"].Value); object keyValuePairValue = GetValue(valueType, jsonKeyValuePairCollection["value"].Value); //Add addMethod.Invoke(value, new object[] { keyValuePairKey, keyValuePairValue }); } } } } //Check if value implements ICollection else if (propertyType.GetInterface(typeof(ICollection <>).Name) != null) { //Prepare Type collectionType = propertyType.GetInterface(typeof(ICollection <>).FullName); Type elementType = collectionType.GetGenericArguments()[0]; MethodInfo addMethod = collectionType.GetMethod("Add"); JsonObject jsonValue = jsonCollection[name].Value; //Deserialize element if (jsonValue is JsonObjectCollection jsonObjects) { foreach (var foo in jsonObjects) { object element = GetValue(elementType, foo); addMethod.Invoke(value, new object[] { element }); } } } //Deserialize else { DeserializeObject(value, propertyType, jsonCollection[name].Value); } } } //Loop through publicly exposed writable fields foreach (var fieldInfo in objectType.GetFields()) { //Prepare string name = fieldInfo.Name; //Check attributes JsonSerializeAttribute attribute = fieldInfo.GetCustomAttribute <JsonSerializeAttribute>(); if (attribute != null) { if (!string.IsNullOrEmpty(attribute.Name)) { name = attribute.Name; } } //Set field value if (jsonCollection.Contains(name) && !fieldInfo.IsInitOnly) { fieldInfo.SetValue(instance, GetValue(fieldInfo.FieldType, jsonCollection[name].Value)); } //Check if field is reference type and is not null. else if (!fieldInfo.FieldType.IsValueType && fieldInfo.GetValue(instance) != null) { //Get instance object value = fieldInfo.GetValue(instance); Type fieldType = fieldInfo.FieldType; //Check if value implements IDictionary if (fieldType.GetInterface(typeof(IDictionary <,>).Name) != null && value is IDictionary dictionary) { //Prepare Type dictionaryType = fieldType.GetInterface(typeof(IDictionary <,>).FullName); Type keyType = dictionaryType.GetGenericArguments()[0]; Type valueType = dictionaryType.GetGenericArguments()[1]; MethodInfo addMethod = dictionaryType.GetMethod("Add"); JsonObject jsonValue = jsonCollection[name].Value; //Loop through key value pairs if (jsonValue is JsonObjectCollection jsonObjects) { foreach (JsonObject jsonKeyValuePair in jsonObjects) { //Check if object is a JSON element collection if (jsonKeyValuePair is JsonElementCollection jsonKeyValuePairCollection) { //Get key and value from the JSON key value pair object keyValuePairKey = GetValue(keyType, jsonKeyValuePairCollection["key"].Value); object keyValuePairValue = GetValue(valueType, jsonKeyValuePairCollection["value"].Value); //Add addMethod.Invoke(value, new object[] { keyValuePairKey, keyValuePairValue }); } } } } //Check if value implements ICollection else if (fieldType.GetInterface(typeof(ICollection <>).Name) != null) { //Prepare Type collectionType = fieldType.GetInterface(typeof(ICollection <>).FullName); Type elementType = collectionType.GetGenericArguments()[0]; MethodInfo addMethod = collectionType.GetMethod("Add"); JsonObject jsonValue = jsonCollection[name].Value; //Deserialize element if (jsonValue is JsonObjectCollection jsonObjects) { foreach (var foo in jsonObjects) { object element = GetValue(elementType, foo); addMethod.Invoke(value, new object[] { element }); } } } //Deserialize else { DeserializeObject(value, fieldType, jsonCollection[name].Value); } } } }
private JsonElementCollection SerializeObject(object @object) { //Prepare JsonElementCollection collection = new JsonElementCollection(); JsonSerializeAttribute attribute; //Check if (@object == null) { throw new ArgumentNullException(nameof(@object)); } Type objectType = @object.GetType(); //Loop through properties in object foreach (PropertyInfo propertyInfo in objectType.GetProperties()) { //Prepare JsonElement element = new JsonElement() { Name = propertyInfo.Name }; try { //Get property value object propertyValue = propertyInfo.GetValue(@object); if (propertyValue is Delegate) { element.Value = new JsonNull(); } else if (propertyValue is Type type) { element.Value = new JsonString() { Value = type.AssemblyQualifiedName } } ; else { //Get JsonSerializeAttribute attribute = propertyInfo.GetCustomAttribute <JsonSerializeAttribute>(); if (attribute != null) { //Check name if (!string.IsNullOrEmpty(attribute.Name)) { element.Name = attribute.Name; } } //Set value element.Value = Serialize(propertyValue); } } catch { element.Value = new JsonNull(); } //Add element collection.Add(element); } //Loop through fields in object foreach (FieldInfo fieldInfo in objectType.GetFields()) { //Prepare JsonElement element = new JsonElement() { Name = fieldInfo.Name }; try { //Get field value object fieldValue = fieldInfo.GetValue(@object); //Get JsonSerializeAttribute attribute = fieldInfo.GetCustomAttribute <JsonSerializeAttribute>(); if (attribute != null) { //Check name if (!string.IsNullOrEmpty(attribute.Name)) { element.Name = attribute.Name; } } //Set value element.Value = Serialize(fieldValue); } catch { element.Value = new JsonNull(); } //Add element collection.Add(element); } //Return return(collection); }
/// <summary> /// Converts the specified string to a JSON object. /// </summary> /// <param name="json">The JSON string. This value can be null.</param> /// <returns>A JSON object representing the specified string.</returns> public static JsonObject Parse(string json) { //Check if (string.IsNullOrEmpty(json)) { return(new JsonNull()); } //Create reader using (JsonStringReader reader = new JsonStringReader(json)) { //Read first token if (reader.PeekToken() == -1) { return(new JsonNull()); } string token = reader.ReadToken(); //Check peek char switch (GetTokenType(token)) { case JsonTokenType.Number: return(new JsonNumber() { Value = decimal.Parse(token) }); case JsonTokenType.String: return(new JsonString() { Value = FormatString(token) }); case JsonTokenType.Collection: JsonElementCollection collection = new JsonElementCollection(); using (JsonStringReader collectionReader = new JsonStringReader(token)) { //Read open brace collectionReader.Read(); //Loop while (collectionReader.PeekToken() != '}') { //Read key-value pair string nameToken = collectionReader.ReadString(); collectionReader.ReadToken(); string valueToken = collectionReader.ReadToken(); //Check if (collectionReader.PeekToken() == ',') { collectionReader.ReadToken(); } collection.Add(new JsonElement() { Name = FormatString(nameToken), Value = Parse(valueToken) }); } //Read close brace collectionReader.Read(); } return(collection); case JsonTokenType.Array: JsonObjectCollection array = new JsonObjectCollection(); using (JsonStringReader arrayReader = new JsonStringReader(token)) { //Read open bracket arrayReader.Read(); //Loop while (arrayReader.PeekToken() != ']') { //Read object string elementToken = arrayReader.ReadToken(); //Check if (arrayReader.PeekToken() == ',') { arrayReader.ReadToken(); } array.Add(Parse(elementToken)); } //Read close bracket arrayReader.Read(); } return(array); case JsonTokenType.Literal: if (token == "true" || token == "false") { return new JsonBoolean() { Value = bool.Parse(token) } } ; else if (token == "null") { return(new JsonNull()); } throw new InvalidDataException("Only the 'true', 'false', and 'null' literals are supported."); } } //Return return(null); }