protected override JsonObjectContract CreateObjectContract(Type objectType) { var contract = base.CreateObjectContract(objectType); var objectTypeInfo = objectType.GetTypeInfo(); if (TypeData <ExtensibleObject> .TypeInfo.IsAssignableFrom(objectTypeInfo)) { contract.ExtensionDataGetter = o => ((DirtyDictionary <string, object>)((ExtensibleObject)o).ExtensionData).GetDirtyItems().Select(p => new KeyValuePair <object, object>(p.Key, p.Value)); contract.ExtensionDataSetter = (o, k, v) => ((ExtensibleObject)o).ExtensionData[k] = v; if (TypeData <DirtyExtensibleObject> .TypeInfo.IsAssignableFrom(objectTypeInfo)) { var idPropertyName = DirtyExtensibleObject.GetIdPropertyName(objectTypeInfo); var backingFieldTypeInfo = GetBackingFieldInfo(objectType, idPropertyName)?.FieldInfo.FieldType.GetTypeInfo(); idPropertyName = CamelCaseNamingStrategy.GetPropertyName(idPropertyName, false); var idProperty = contract.Properties.GetClosestMatchProperty(idPropertyName); if (idProperty != null && (backingFieldTypeInfo == null || !backingFieldTypeInfo.IsGenericType || backingFieldTypeInfo.IsGenericTypeDefinition || backingFieldTypeInfo.GetGenericTypeDefinition() != TypeData.OpenNeverSerializeValueType)) { idProperty.ShouldSerialize = o => ((IIdentifiable)o).Id != null; } ReadEntityAttributes(objectTypeInfo, contract); } } return(contract); }
protected override JsonObjectContract CreateObjectContract(Type objectType) { var contract = base.CreateObjectContract(objectType); var objectTypeInfo = objectType.GetTypeInfo(); if (TypeData <ExtensibleObject> .TypeInfo.IsAssignableFrom(objectTypeInfo)) { contract.ExtensionDataGetter = o => ((DirtyDictionary <string, object>)((ExtensibleObject)o).ExtensionData).GetDirtyItems().Select(p => new KeyValuePair <object, object>(p.Key, p.Value)); contract.ExtensionDataSetter = (o, k, v) => ((ExtensibleObject)o).ExtensionData[k] = v; if (TypeData <DirtyExtensibleObject> .TypeInfo.IsAssignableFrom(objectTypeInfo)) { var idPropertyName = DirtyExtensibleObject.GetIdPropertyName(objectTypeInfo); var backingFieldTypeInfo = GetBackingFieldInfo(objectType, idPropertyName)?.FieldInfo.FieldType.GetTypeInfo(); idPropertyName = CamelCaseNamingStrategy.GetPropertyName(idPropertyName, false); var property = contract.Properties.GetClosestMatchProperty(idPropertyName); if (property != null && (backingFieldTypeInfo == null || !backingFieldTypeInfo.IsGenericType || backingFieldTypeInfo.IsGenericTypeDefinition || backingFieldTypeInfo.GetGenericTypeDefinition() != TypeData.OpenNeverSerializeValueType)) { property.ShouldSerialize = o => ((IIdentifiable)o).Id != null; } var entityAttribute = objectTypeInfo.GetCustomAttribute <EntityAttribute>(false); if (entityAttribute != null && !string.IsNullOrEmpty(entityAttribute.PropertiesToAlwaysSerialize)) { var propertiesToAlwaysSerialize = entityAttribute.PropertiesToAlwaysSerialize.Split(','); foreach (var propertyToAlwaysSerialize in propertiesToAlwaysSerialize) { property = contract.Properties.GetClosestMatchProperty(propertyToAlwaysSerialize); var valueProvider = property.ValueProvider; property.ShouldSerialize = o => valueProvider.GetValue(o) != null; } } } } return(contract); }
private static void PopulateArray(JArray jArray, JsonArrayContract arrayContract, IList source, IList target) { if (target.Count > 0 && target is IEnumerable <DirtyExtensibleObject> targetEnumerable) { var objectContract = (JsonObjectContract)InternalPrivateContractResolver.ResolveContract(arrayContract.CollectionItemType); var sourceEnumerable = (IEnumerable <DirtyExtensibleObject>)source; for (var i = target.Count - 1; i >= 0; --i) { var targetItem = (DirtyExtensibleObject)target[i]; var id = ((IIdentifiable)targetItem)?.Id; if (!string.IsNullOrEmpty(id) && Extensions.IndexOf(sourceEnumerable, id) < 0) { target.RemoveAt(i); targetItem.ClearPropertyChangedEvent(); } } for (var i = 0; i < source.Count; ++i) { var sourceItem = (DirtyExtensibleObject)source[i]; if (i == target.Count) { target.Add(sourceItem); } else { DirtyExtensibleObject existing = null; var id = ((IIdentifiable)sourceItem)?.Id; int index; if (!string.IsNullOrEmpty(id) && (index = Extensions.IndexOf(targetEnumerable, id)) >= i) { existing = (DirtyExtensibleObject)target[index]; for (var j = i; j < index; ++j) { target[j + 1] = target[j]; } target[i] = existing; } else { existing = (DirtyExtensibleObject)target[i]; if (!string.IsNullOrEmpty(((IIdentifiable)existing)?.Id)) { target.Insert(i, sourceItem); existing = null; } } if (existing != null) { PopulateObject((JObject)jArray[i], objectContract, sourceItem, existing); } } } for (var i = target.Count - 1; i >= source.Count; --i) { var targetItem = (DirtyExtensibleObject)target[i]; target.RemoveAt(i); targetItem.ClearPropertyChangedEvent(); } } else { target.Clear(); foreach (var item in source) { target.Add(item); } } }