private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; for (int index = 0; index < contract.Properties.Count; index++) { JsonProperty property = contract.Properties[index]; // only write non-dynamic properties that have an explicit attribute if (property.HasMemberAttribute) { try { object memberValue; JsonContract memberContract; if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) { continue; } property.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, property, contract, member); } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } } foreach (string memberName in value.GetDynamicMemberNames()) { object memberValue; if (contract.TryGetMember(value, memberName, out memberValue)) { try { JsonContract valueContract = GetContractSafe(memberValue); if (!ShouldWriteDynamicProperty(memberValue)) { continue; } if (CheckForCircularReference(writer, memberValue, null, valueContract, contract, member)) { string resolvedPropertyName = (contract.PropertyNameResolver != null) ? contract.PropertyNameResolver(memberName) : memberName; writer.WritePropertyName(resolvedPropertyName); SerializeValue(writer, memberValue, valueContract, null, contract, member); } } catch (Exception ex) { if (IsErrorHandled(value, contract, memberName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); }
private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, out JsonContract memberContract, out object memberValue) { if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value)) { if (property.PropertyContract == null) property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); memberValue = property.ValueProvider.GetValue(value); memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue); if (ShouldWriteProperty(memberValue, property)) { if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) { property.WritePropertyName(writer); WriteReference(writer, memberValue); return false; } if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member)) return false; if (memberValue == null) { JsonObjectContract objectContract = contract as JsonObjectContract; Required resolvedRequired = property._required ?? ((objectContract != null) ? objectContract.ItemRequired : null) ?? Required.Default; if (resolvedRequired == Required.Always) throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); } return true; } } memberContract = null; memberValue = null; return false; }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; for (int index = 0; index < contract.Properties.Count; index++) { JsonProperty property = contract.Properties[index]; try { object memberValue; JsonContract memberContract; if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) { continue; } property.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, property, contract, member); } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } if (contract.ExtensionDataGetter != null) { IEnumerable <KeyValuePair <object, object> > extensionData = contract.ExtensionDataGetter(value); if (extensionData != null) { foreach (KeyValuePair <object, object> e in extensionData) { JsonContract keyContract = GetContractSafe(e.Key); JsonContract valueContract = GetContractSafe(e.Value); bool escape; string propertyName = GetPropertyName(writer, e.Key, keyContract, out escape); if (ShouldWriteReference(e.Value, null, valueContract, contract, member)) { writer.WritePropertyName(propertyName); WriteReference(writer, e.Value); } else { if (!CheckForCircularReference(writer, e.Value, null, valueContract, contract, member)) { continue; } writer.WritePropertyName(propertyName); SerializeValue(writer, e.Value, valueContract, null, contract, member); } } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); }