private static void ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary <string, object> deserialzedValue, object newInstance, XmlObjectSerializerReadContextComplexJson context) { if (dataContract.BaseContract != null) { ReadClassDataContractMembers(serializer, dataContract.BaseContract, deserialzedValue, newInstance, context); } for (int i = 0; i < dataContract.Members.Count; i++) { DataMember member = dataContract.Members[i]; object currentMemberValue; if (deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name), out currentMemberValue) || dataContract.IsKeyValuePairAdapter && deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name.ToLowerInvariant()), out currentMemberValue)) { if (member.MemberType.GetTypeInfo().IsPrimitive || currentMemberValue == null) { SetMemberValue(newInstance, serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context), dataContract.Members[i].MemberInfo, dataContract.UnderlyingType); } else { context.PushKnownTypes(dataContract); object subMemberValue = serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context); Type declaredType = (member.MemberType.GetTypeInfo().IsGenericType&& member.MemberType.GetGenericTypeDefinition() == Globals.TypeOfNullable) ? Nullable.GetUnderlyingType(member.MemberType) : member.MemberType; if (!(declaredType == Globals.TypeOfObject && subMemberValue.GetType() == Globals.TypeOfObjectArray) && declaredType != subMemberValue.GetType()) { DataContract memberValueContract = DataContract.GetDataContract(subMemberValue.GetType()); context.CheckIfTypeNeedsVerifcation(member.MemberTypeContract, memberValueContract); } if (member.IsGetOnlyCollection) { PopulateReadOnlyCollection(newInstance, member, (IEnumerable)subMemberValue); } else { SetMemberValue(newInstance, subMemberValue, dataContract.Members[i].MemberInfo, dataContract.UnderlyingType); } context.PopKnownTypes(dataContract); } } else if (member.IsRequired) { XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(dataContract.MemberNames[i].Value, dataContract.UnderlyingType); } } }
private static void ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary<string, object> deserialzedValue, object newInstance, XmlObjectSerializerReadContextComplexJson context) { if (dataContract.BaseContract != null) { ReadClassDataContractMembers(serializer, dataContract.BaseContract, deserialzedValue, newInstance, context); } for (int i = 0; i < dataContract.Members.Count; i++) { DataMember member = dataContract.Members[i]; object currentMemberValue; if (deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name), out currentMemberValue) || dataContract.IsKeyValuePairAdapter && deserialzedValue.TryGetValue(XmlConvert.DecodeName(dataContract.Members[i].Name.ToLowerInvariant()), out currentMemberValue)) { if (member.MemberType.GetTypeInfo().IsPrimitive || currentMemberValue == null) { SetMemberValue(newInstance, serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context), dataContract.Members[i].MemberInfo, dataContract.UnderlyingType); } else { context.PushKnownTypes(dataContract); object subMemberValue = serializer.ConvertObjectToDataContract(member.MemberTypeContract, currentMemberValue, context); Type declaredType = (member.MemberType.GetTypeInfo().IsGenericType && member.MemberType.GetGenericTypeDefinition() == Globals.TypeOfNullable) ? Nullable.GetUnderlyingType(member.MemberType) : member.MemberType; if (!(declaredType == Globals.TypeOfObject && subMemberValue.GetType() == Globals.TypeOfObjectArray) && declaredType != subMemberValue.GetType()) { DataContract memberValueContract = DataContract.GetDataContract(subMemberValue.GetType()); context.CheckIfTypeNeedsVerifcation(member.MemberTypeContract, memberValueContract); } if (member.IsGetOnlyCollection) { PopulateReadOnlyCollection(newInstance, member, (IEnumerable)subMemberValue); } else { SetMemberValue(newInstance, subMemberValue, dataContract.Members[i].MemberInfo, dataContract.UnderlyingType); } context.PopKnownTypes(dataContract); } } else if (member.IsRequired) { XmlObjectSerializerWriteContext.ThrowRequiredMemberMustBeEmitted(dataContract.MemberNames[i].Value, dataContract.UnderlyingType); } } }
//Deserialize '[...]' json string. The contents of the list can also be a dictionary i.e. [{...}]. The content type is detected //based on the type of CollectionDataContract.ItemContract. public static object ConvertICollectionToCollectionDataContract(DataContractJsonSerializer serializer, CollectionDataContract contract, object deserializedValue, XmlObjectSerializerReadContextComplexJson context) { Dictionary <string, object> valueAsDictionary = deserializedValue as Dictionary <string, object>; //Check to see if the dictionary (if it is a dictionary)is a regular Dictionary i.e { Key="key"; Value="value} and doesnt contain the __type string //for ex. the dictionary { __type="XXX"; Key="key"; Value="value} needs to be parsed as ClassDataContract if (valueAsDictionary != null && (!valueAsDictionary.ContainsKey(JsonGlobals.KeyString) || valueAsDictionary.ContainsKey(JsonGlobals.ServerTypeString))) { //If not then its a dictionary for either of these cases //1. Empty object - {} //2. Containes the __type information //3. Is a DateTimeOffsetDictionary return(ConvertDictionary(serializer, contract, valueAsDictionary, context)); } object returnValue = (contract.Constructor != null) ? contract.Constructor.Invoke(Globals.EmptyTypeArray) : null; bool isCollectionDataContractDictionary = contract.IsDictionary; MethodInfo addMethod = contract.AddMethod; bool convertToArray = contract.Kind == CollectionKind.Array; if (contract.UnderlyingType.GetTypeInfo().IsInterface || returnValue == null) { switch (contract.Kind) { case CollectionKind.Collection: case CollectionKind.GenericCollection: case CollectionKind.Enumerable: case CollectionKind.GenericEnumerable: case CollectionKind.List: case CollectionKind.GenericList: case CollectionKind.Array: if (contract.UnderlyingType.GetTypeInfo().IsValueType) { //Initialize struct returnValue = XmlFormatReaderGenerator.TryGetUninitializedObjectWithFormatterServices(contract.UnderlyingType); } else { returnValue = Activator.CreateInstance(Globals.TypeOfListGeneric.MakeGenericType(contract.ItemType)); convertToArray = true; } break; case CollectionKind.GenericDictionary: returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(contract.ItemType.GetGenericArguments())); break; case CollectionKind.Dictionary: returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(Globals.TypeOfObject, Globals.TypeOfObject)); break; } } if (addMethod == null) { //addMethod is null for IDictionary, IList and array types. Type[] paramArray = (contract.ItemType.GetTypeInfo().IsGenericType&& !convertToArray) ? contract.ItemType.GetGenericArguments() : new Type[] { contract.ItemType }; addMethod = returnValue.GetType().GetMethod(Globals.AddMethodName, paramArray); } IEnumerator enumerator = ((ICollection)deserializedValue).GetEnumerator(); object currentItem = null; object[] currentItemArray = null; while (enumerator.MoveNext()) { DataContract itemContract = contract.ItemContract; if (itemContract is ClassDataContract) { itemContract = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(itemContract); } currentItem = serializer.ConvertObjectToDataContract(itemContract, enumerator.Current, context); currentItemArray = new object[] { currentItem }; if (isCollectionDataContractDictionary) { Type currentItemType = currentItem.GetType(); MemberInfo keyMember = currentItemType.GetMember("Key")[0]; MemberInfo valueMember = currentItemType.GetMember("Value")[0]; currentItemArray = new object[] { DataContractToObjectConverter.GetMemberValue(currentItem, keyMember, currentItemType), DataContractToObjectConverter.GetMemberValue(currentItem, valueMember, currentItemType) }; } addMethod.Invoke(returnValue, currentItemArray); } return((convertToArray) ? ConvertToArray(contract.ItemType, (ICollection)returnValue) : returnValue); }
//Deserialize '[...]' json string. The contents of the list can also be a dictionary i.e. [{...}]. The content type is detected //based on the type of CollectionDataContract.ItemContract. public static object ConvertICollectionToCollectionDataContract(DataContractJsonSerializer serializer, CollectionDataContract contract, object deserializedValue, XmlObjectSerializerReadContextComplexJson context) { Dictionary<string, object> valueAsDictionary = deserializedValue as Dictionary<string, object>; //Check to see if the dictionary (if it is a dictionary)is a regular Dictionary i.e { Key="key"; Value="value} and doesnt contain the __type string //for ex. the dictionary { __type="XXX"; Key="key"; Value="value} needs to be parsed as ClassDataContract if (valueAsDictionary != null && (!valueAsDictionary.ContainsKey(JsonGlobals.KeyString) || valueAsDictionary.ContainsKey(JsonGlobals.ServerTypeString))) { //If not then its a dictionary for either of these cases //1. Empty object - {} //2. Containes the __type information //3. Is a DateTimeOffsetDictionary return ConvertDictionary(serializer, contract, valueAsDictionary, context); } object returnValue = (contract.Constructor != null) ? contract.Constructor.Invoke(Array.Empty<Type>()) : null; bool isCollectionDataContractDictionary = contract.IsDictionary; MethodInfo addMethod = contract.AddMethod; bool convertToArray = contract.Kind == CollectionKind.Array; if (contract.UnderlyingType.GetTypeInfo().IsInterface || returnValue == null) { switch (contract.Kind) { case CollectionKind.Collection: case CollectionKind.GenericCollection: case CollectionKind.Enumerable: case CollectionKind.GenericEnumerable: case CollectionKind.List: case CollectionKind.GenericList: case CollectionKind.Array: if (contract.UnderlyingType.GetTypeInfo().IsValueType) { //Initialize struct returnValue = XmlFormatReaderGenerator.TryGetUninitializedObjectWithFormatterServices(contract.UnderlyingType); } else { returnValue = Activator.CreateInstance(Globals.TypeOfListGeneric.MakeGenericType(contract.ItemType)); convertToArray = true; } break; case CollectionKind.GenericDictionary: returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(contract.ItemType.GetGenericArguments())); break; case CollectionKind.Dictionary: returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(Globals.TypeOfObject, Globals.TypeOfObject)); break; } } if (addMethod == null) { //addMethod is null for IDictionary, IList and array types. Type[] paramArray = (contract.ItemType.GetTypeInfo().IsGenericType && !convertToArray) ? contract.ItemType.GetGenericArguments() : new Type[] { contract.ItemType }; addMethod = returnValue.GetType().GetMethod(Globals.AddMethodName, paramArray); } IEnumerator enumerator = ((ICollection)deserializedValue).GetEnumerator(); object currentItem = null; object[] currentItemArray = null; while (enumerator.MoveNext()) { DataContract itemContract = contract.ItemContract; if (itemContract is ClassDataContract) { itemContract = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(itemContract); } currentItem = serializer.ConvertObjectToDataContract(itemContract, enumerator.Current, context); currentItemArray = new object[] { currentItem }; if (isCollectionDataContractDictionary) { Type currentItemType = currentItem.GetType(); MemberInfo keyMember = currentItemType.GetMember("Key")[0]; MemberInfo valueMember = currentItemType.GetMember("Value")[0]; currentItemArray = new object[] { DataContractToObjectConverter.GetMemberValue(currentItem, keyMember, currentItemType), DataContractToObjectConverter.GetMemberValue(currentItem, valueMember, currentItemType) }; } addMethod.Invoke(returnValue, currentItemArray); } return (convertToArray) ? ConvertToArray(contract.ItemType, (ICollection)returnValue) : returnValue; }