private static bool HandleDictionary( JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, ref WriteStack state) { JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; if (!jsonPropertyInfo.ShouldSerialize) { // Ignore writing this property. return(true); } if (state.Current.Enumerator == null) { // Verify that the Dictionary can be serialized by having <string> as first generic argument. Type[] args = jsonPropertyInfo.RuntimePropertyType.GetGenericArguments(); if (args.Length == 0 || args[0].UnderlyingSystemType != typeof(string)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type, state.PropertyPath); } IEnumerable enumerable = (IEnumerable)jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); if (enumerable == null) { // Write a null object or enumerable. state.Current.WriteObjectOrArrayStart(ClassType.Dictionary, writer, writeNull: true); return(true); } state.Current.Enumerator = enumerable.GetEnumerator(); state.Current.WriteObjectOrArrayStart(ClassType.Dictionary, writer); } if (state.Current.Enumerator.MoveNext()) { // Check for polymorphism. if (elementClassInfo.ClassType == ClassType.Unknown) { object currentValue = ((IDictionaryEnumerator)state.Current.Enumerator).Entry; GetRuntimeClassInfo(currentValue, ref elementClassInfo, options); } if (elementClassInfo.ClassType == ClassType.Value) { elementClassInfo.GetPolicyProperty().WriteDictionary(options, ref state.Current, writer); } else if (state.Current.Enumerator.Current == null) { writer.WriteNull(jsonPropertyInfo.Name); } else { // An object or another enumerator requires a new stack frame. var enumerator = (IDictionaryEnumerator)state.Current.Enumerator; object value = enumerator.Value; state.Push(elementClassInfo, value); state.Current.KeyName = (string)enumerator.Key; } return(false); } // We are done enumerating. writer.WriteEndObject(); if (state.Current.PopStackOnEnd) { state.Pop(); } else { state.Current.EndDictionary(); } return(true); }
private static bool HandleEnumerable( JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, ref WriteStack state) { Debug.Assert(state.Current.JsonPropertyInfo.ClassType == ClassType.Enumerable); if (state.Current.Enumerator == null) { IEnumerable enumerable = (IEnumerable)state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); if (enumerable == null) { if (!state.Current.JsonPropertyInfo.IgnoreNullValues) { // Write a null object or enumerable. state.Current.WriteObjectOrArrayStart(ClassType.Enumerable, writer, writeNull: true); } return(true); } state.Current.Enumerator = enumerable.GetEnumerator(); state.Current.WriteObjectOrArrayStart(ClassType.Enumerable, writer); } if (state.Current.Enumerator.MoveNext()) { // Check for polymorphism. if (elementClassInfo.ClassType == ClassType.Unknown) { object currentValue = state.Current.Enumerator.Current; GetRuntimeClassInfo(currentValue, ref elementClassInfo, options); } if (elementClassInfo.ClassType == ClassType.Value) { elementClassInfo.GetPolicyProperty().WriteEnumerable(ref state.Current, writer); } else if (state.Current.Enumerator.Current == null) { // Write a null object or enumerable. writer.WriteNullValue(); } else { // An object or another enumerator requires a new stack frame. object nextValue = state.Current.Enumerator.Current; state.Push(elementClassInfo, nextValue); } return(false); } // We are done enumerating. writer.WriteEndArray(); if (state.Current.PopStackOnEnd) { state.Pop(); } else { state.Current.EndArray(); } return(true); }