private static void WriteValue(object obj, JsonWriter writer, bool writer_is_private, int depth) { if (depth > max_nesting_depth) { throw new JsonException( String.Format("Max allowed object depth reached while " + "trying to export from type {0}", obj.GetType())); } if (obj == null) { writer.Write(null); return; } if (obj is IJsonWrapper) { if (writer_is_private) { writer.TextWriter.Write(((IJsonWrapper)obj).ToJson()); } else { ((IJsonWrapper)obj).ToJson(writer); } return; } if (obj is String) { writer.Write((string)obj); return; } if (obj is Double) { writer.Write((double)obj); return; } if (obj is Int32) { writer.Write((int)obj); return; } if (obj is Boolean) { writer.Write((bool)obj); return; } if (obj is Int64) { writer.Write((long)obj); return; } if (obj is Array) { writer.WriteArrayStart(); foreach (object elem in (Array)obj) { WriteValue(elem, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IList) { writer.WriteArrayStart(); foreach (object elem in (IList)obj) { WriteValue(elem, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IDictionary) { writer.WriteObjectStart(); foreach (DictionaryEntry entry in (IDictionary)obj) { writer.WritePropertyName((string)entry.Key); WriteValue(entry.Value, writer, writer_is_private, depth + 1); } writer.WriteObjectEnd(); return; } Type obj_type = obj.GetType(); // See if there's a custom exporter for the object if (custom_exporters_table.ContainsKey(obj_type)) { ExporterFunc exporter = custom_exporters_table[obj_type]; exporter(obj, writer); return; } // If not, maybe there's a base exporter if (base_exporters_table.ContainsKey(obj_type)) { ExporterFunc exporter = base_exporters_table[obj_type]; exporter(obj, writer); return; } // Last option, let's see if it's an enum if (obj is Enum) { Type e_type = Enum.GetUnderlyingType(obj_type); if (e_type == typeof(long) || e_type == typeof(uint) || e_type == typeof(ulong)) { writer.Write((ulong)obj); } else { writer.Write((int)obj); } return; } // Okay, so it looks like the input should be exported as an // object AddTypeProperties(obj_type); IList <PropertyMetadata> props = type_properties[obj_type]; writer.WriteObjectStart(); foreach (PropertyMetadata p_data in props) { if (JsonIgnoreAttribute.Ignore(p_data.Info)) { continue; } JsonPropertyAttribute jsonPropertyAttribute = p_data.Info.GetCustomAttribute <JsonPropertyAttribute>(); string propertyName = jsonPropertyAttribute == null ? p_data.Info.Name : jsonPropertyAttribute.JsonProperty; if (p_data.IsField) { writer.WritePropertyName(propertyName); WriteValue(((FieldInfo)p_data.Info).GetValue(obj), writer, writer_is_private, depth + 1); } else { PropertyInfo p_info = (PropertyInfo)p_data.Info; if (p_info.CanRead) { writer.WritePropertyName(propertyName); WriteValue(p_info.GetValue(obj, null), writer, writer_is_private, depth + 1); } } } writer.WriteObjectEnd(); }
private static void AddObjectMetadata(Type type) { if (object_metadata.ContainsKey(type)) { return; } ObjectMetadata data = new ObjectMetadata(); if (type.GetInterface("System.Collections.IDictionary") != null) { data.IsDictionary = true; } data.Properties = new Dictionary <string, PropertyMetadata> (); foreach (PropertyInfo p_info in type.GetProperties()) { if (p_info.Name == "Item") { ParameterInfo[] parameters = p_info.GetIndexParameters(); if (parameters.Length != 1) { continue; } if (parameters[0].ParameterType == typeof(string)) { data.ElementType = p_info.PropertyType; } continue; } if (!JsonIgnoreAttribute.Ignore(p_info)) { PropertyMetadata p_data = new PropertyMetadata(); p_data.Info = p_info; p_data.Type = p_info.PropertyType; JsonPropertyAttribute jsonPropertyAttribute = p_info.GetCustomAttribute <JsonPropertyAttribute>(); string propertyName = jsonPropertyAttribute == null ? p_info.Name : jsonPropertyAttribute.JsonProperty; data.Properties.Add(propertyName, p_data); } } foreach (FieldInfo f_info in type.GetFields()) { if (!JsonIgnoreAttribute.Ignore(f_info)) { PropertyMetadata p_data = new PropertyMetadata(); p_data.Info = f_info; p_data.IsField = true; p_data.Type = f_info.FieldType; JsonPropertyAttribute jsonPropertyAttribute = f_info.GetCustomAttribute <JsonPropertyAttribute>(); string propertyName = jsonPropertyAttribute == null ? f_info.Name : jsonPropertyAttribute.JsonProperty; data.Properties.Add(propertyName, p_data); } } lock (object_metadata_lock) { try { object_metadata.Add(type, data); } catch (ArgumentException) { return; } } }