/// <summary> /// Get the specified formatter /// </summary> /// <param name="type">The type to retrieve the formatter for</param> public IJsonViewModelTypeFormatter GetFormatter(Type type) { IJsonViewModelTypeFormatter typeFormatter = null; if (!this.m_formatters.TryGetValue(type, out typeFormatter)) { typeFormatter = new JsonReflectionTypeFormatter(type); lock (this.m_syncLock) if (!this.m_formatters.ContainsKey(type)) { this.m_formatters.Add(type, typeFormatter); } } return(typeFormatter); }
/// <summary> /// Write property utility /// </summary> public void WritePropertyUtil(JsonWriter w, String propertyName, Object instance, SerializationContext context, bool noSubContext = false) { if (instance == null) { return; } // first write the property if (!String.IsNullOrEmpty(propertyName)) // In an array so don't emit the property name { w.WritePropertyName(propertyName); // Are we to never serialize this? if (context?.ShouldSerialize(propertyName) == false && !noSubContext) { w.WriteNull(); return; } } if (instance is IdentifiedData) { var identifiedData = instance as IdentifiedData; // Complex type .. allow the formatter to handle this IJsonViewModelTypeFormatter typeFormatter = this.GetFormatter(instance.GetType()); var simpleValue = typeFormatter.GetSimpleValue(instance); if (simpleValue != null && propertyName != "$other") // Special case for $other { w.WriteValue(simpleValue); } else { w.WriteStartObject(); var subContext = noSubContext && w.Path.EndsWith("]") ? context as JsonSerializationContext : new JsonSerializationContext(propertyName, this, instance, context as JsonSerializationContext); this.WriteSimpleProperty(w, "$type", identifiedData.Type); this.WriteSimpleProperty(w, "$id", String.Format("obj{0}", subContext.ObjectId)); // Write ref var parentObjectId = context?.GetParentObjectId(identifiedData); if (parentObjectId.HasValue) // Recursive { this.WriteSimpleProperty(w, "$ref", String.Format("#obj{0}", parentObjectId.Value)); } else { typeFormatter.Serialize(w, instance as IdentifiedData, subContext); } w.WriteEndObject(); } } else if (instance is IList && !instance.GetType().IsArray) { // Classifications? var classifier = this.GetClassifier(instance.GetType().StripNullable()); if (classifier == null) // no classifier { w.WriteStartArray(); foreach (var itm in instance as IList) { this.WritePropertyUtil(w, null, itm, new JsonSerializationContext(propertyName, this, instance, context as JsonSerializationContext), noSubContext); } w.WriteEndArray(); } else { w.WriteStartObject(); foreach (var cls in classifier.Classify(instance as IList)) { Object value = new List <Object>(cls.Value as IEnumerable <Object>); if (cls.Value.Count == 1) { value = cls.Value[0]; } // Now write this.WritePropertyUtil(w, cls.Key, value, new JsonSerializationContext(propertyName, this, instance, context as JsonSerializationContext), true); } w.WriteEndObject(); } } else { w.WriteValue(instance); } }