/// <summary> /// Goes through a deserialized JSON object (a Dictionary<string, object> or a newtonsoft JObject) and updates all field an properties of this instance. /// </summary> /// <param name="value">The value.</param> public void FromJsonIntermediateObject(object value) { if (value == null) { // TODO: what should the method do then? return; } Type type = this.GetType(); MemberInfo[] fieldAndPropertyInfos = type.GetProperties().Select(prop => (MemberInfo)prop).Union(type.GetFields().Select(field => (MemberInfo)field)).ToArray(); // we do this here so there's no need to repeatedly cast the object within each pass of each for loop JObject valueAsJObject = value as JObject; Dictionary <string, object> valueAsDictionary = value as Dictionary <string, object>; if (valueAsJObject == null && valueAsDictionary == null) { throw new FormatException("Unsupported intermediate format"); } foreach (MemberInfo member in fieldAndPropertyInfos) { FieldInfo field = member as FieldInfo; PropertyInfo property = member as PropertyInfo; object[] allAtributes = member.GetCustomAttributes(true); // If we don't have any custom attributes for this member, ignore it if (allAtributes == null) { continue; } JsonNameAttribute nameAttribute = allAtributes.FirstOrDefault(attribute => attribute is JsonNameAttribute) as JsonNameAttribute; // If we don't have a JsonName attribute for this member, ignore it if (nameAttribute == null) { continue; } string jsonPropertyName = nameAttribute.Name; Type memberType = field == null ? property.PropertyType : field.FieldType; object memberValue = null; if (valueAsJObject != null && valueAsJObject[jsonPropertyName] != null) { memberValue = valueAsJObject[jsonPropertyName]; } else if (valueAsDictionary != null && valueAsDictionary.ContainsKey(jsonPropertyName)) { memberValue = valueAsDictionary[jsonPropertyName]; } this.SetMemberValue(member, ConvertMember(memberValue, memberType)); } }
/// <summary> /// Converts this instance to a Dictionary<string, object> that is ready to be serialized to a Ruby-compatible JSON. /// </summary> /// <returns>A Dictionary<string, object></returns> public Dictionary <string, object> ToJsonIntermediateObject() { Dictionary <string, object> result = new Dictionary <string, object>(); Type type = this.GetType(); MemberInfo[] fieldAndPropertyInfos = type.GetProperties().Select(prop => (MemberInfo)prop).Union(type.GetFields().Select(field => (MemberInfo)field)).ToArray(); foreach (MemberInfo member in fieldAndPropertyInfos) { FieldInfo field = member as FieldInfo; PropertyInfo property = member as PropertyInfo; object[] allAtributes = member.GetCustomAttributes(true); if (allAtributes != null) { JsonNameAttribute nameAttribute = allAtributes.FirstOrDefault(attribute => attribute is JsonNameAttribute) as JsonNameAttribute; object memberValue = property == null?field.GetValue(this) : property.GetValue(this, null); if (nameAttribute != null && memberValue != null) { string jsonPropertyName = nameAttribute.Name; Type propertyType = property == null ? field.FieldType : property.PropertyType; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { propertyType = propertyType.GetGenericArguments()[0]; } if (propertyType.IsSubclassOf(typeof(JsonConvertibleObject))) { result.Add(jsonPropertyName, ((JsonConvertibleObject)memberValue).ToJsonIntermediateObject()); } else if (propertyType.IsEnum) { string value = memberValue.ToString(); JsonNameAttribute[] attributes = (JsonNameAttribute[])propertyType.GetMember(value)[0].GetCustomAttributes(typeof(JsonNameAttribute), false); if (attributes.Length != 0) { result.Add(jsonPropertyName, attributes[0].Name); } else { result.Add(jsonPropertyName, memberValue.ToString()); } } else { if (memberValue != null) { result.Add(jsonPropertyName, memberValue); } } } } } return(result); }