private XElement serializeCollectionElement(MemberInfo memberInfo, Type memberType, object element, object parentItem, int arrayDimension) { object elementKey = null; object elementToSerialize = element; Type typeToSerialize = memberType; if (memberType.IsGenericType && (memberType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))) { PropertyInfo keyPropertyInfo = memberType.GetProperty(nameof(KeyValuePair <object, object> .Key)); PropertyInfo valuePropertyInfo = memberType.GetProperty(nameof(KeyValuePair <object, object> .Value)); elementKey = keyPropertyInfo.GetValue(element); elementToSerialize = valuePropertyInfo.GetValue(element); typeToSerialize = memberType.GetGenericArguments()[1]; } object arrayElementValue = serializeValue(memberInfo, typeToSerialize, elementToSerialize, parentItem, arrayDimension + 1); PersistAsAttribute persistData = getPersistDataForMember(memberInfo, elementToSerialize, arrayDimension + 1); XElement returnElement = ((arrayElementValue is XElement) && (persistData?.TagName == null)) ? (XElement)arrayElementValue : new XElement(persistData?.TagName ?? UNDEFINED_ARRAY_ITEM_TAG, arrayElementValue); if (elementKey != null) { returnElement.SetAttributeValue(persistData?.KeyAttribute ?? "key", (elementKey is ISystemObject elementKeyObj) ? elementKeyObj.GlobalID : elementKey.ToString()); } return(returnElement); }
private void storeValueOfFieldOrProperty(MemberInfo memberInfo, ref T item, ref XElement xmlElement) { FieldInfo fieldInfo = memberInfo as FieldInfo; PropertyInfo propertyInfo = memberInfo as PropertyInfo; if ((fieldInfo == null) && (propertyInfo == null)) { return; } if ((propertyInfo != null) && !(propertyInfo.CanRead && propertyInfo.CanWrite)) { return; } if (isTemporaryForeignKeyField(memberInfo)) { return; } PersistAsAttribute persistData = getPersistDataForMember(memberInfo, item); if (persistData == null) { return; } object fieldValue = (fieldInfo != null) ? fieldInfo.GetValue(item) : propertyInfo.GetValue(item); Type memberType = (fieldInfo != null) ? fieldInfo.FieldType : propertyInfo.PropertyType; object xmlElementInner = serializeValue(memberInfo, memberType, fieldValue, item); xmlElement.Add(new XElement(persistData.TagName, xmlElementInner)); }
private void restoreValueForFieldOrProperty(MemberInfo memberInfo, Dictionary <string, XmlElement> persistedValues, ref T item) { FieldInfo fieldInfo = memberInfo as FieldInfo; PropertyInfo propertyInfo = memberInfo as PropertyInfo; if ((fieldInfo == null) && (propertyInfo == null)) { return; } if ((propertyInfo != null) && !(propertyInfo.CanRead && propertyInfo.CanWrite)) { return; } if (isAssociationField(memberInfo)) { return; } PersistAsAttribute persistData = getPersistDataForMember(memberInfo, item); if (persistData == null) { return; } if (!persistedValues.TryGetValue(persistData.TagName, out XmlElement xmlElement)) { return; } Type type = (fieldInfo != null) ? fieldInfo.FieldType : propertyInfo.PropertyType; try { object value = deserializeXmlElement(memberInfo, type, xmlElement, item); try { if (fieldInfo != null) { fieldInfo.SetValue(item, value); } else { propertyInfo.SetValue(item, value); } } catch { } } catch (WillRestoreValueLaterException) { } }
private object deserializeArray(MemberInfo memberInfo, Type memberType, List <XmlElement> childElements, object parentItem, int arrayDimension) { int childElementCount = childElements.Count; if (memberType.IsArray) { Type arrayElementType = memberType.GetElementType(); if (Type.GetTypeCode(arrayElementType) != TypeCode.Object) { Array typedArray = Array.CreateInstance(arrayElementType, childElementCount); for (int i = 0; i < childElementCount; i++) { typedArray.SetValue(deserializeXmlElement(memberInfo, arrayElementType, childElements[i], arrayDimension + 1), i); } return(typedArray); } object[] array = (object[])Activator.CreateInstance(memberType, new object[] { childElementCount }); for (int i = 0; i < childElementCount; i++) { array[i] = deserializeXmlElement(memberInfo, memberType.GetElementType(), childElements[i], parentItem, arrayDimension + 1); } return(array); } bool isCollection = false; bool isDictionary = false; Type keyType = null; Type elementType = null; foreach (Type interfaceType in memberType.GetInterfaces()) { if (interfaceType.IsGenericType) { if (interfaceType.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { isDictionary = true; isCollection = true; keyType = interfaceType.GetGenericArguments()[0]; elementType = interfaceType.GetGenericArguments()[1]; break; } if (interfaceType.GetGenericTypeDefinition() == typeof(ICollection <>)) { isCollection = true; elementType = interfaceType.GetGenericArguments()[0]; break; } } } if (isCollection) { if (memberInfo.GetCustomAttribute <PersistDetailedAttribute>() == null) { if (elementType.IsAssignableTo(typeof(ISystemObject)) || (keyType?.IsAssignableTo(typeof(ISystemObject)) == true)) { throw new WillRestoreValueLaterException(); } Type[] genericParams = (keyType != null) ? new Type[] { keyType, elementType } : new Type[] { elementType }; memberType = memberType.GetGenericTypeDefinition().MakeGenericType(genericParams); } object collection = Activator.CreateInstance(memberType, new object[] { }); Type[] addMethodTypes = isDictionary ? new Type[] { keyType, elementType } : new Type[] { elementType }; MethodInfo addMethod = memberType.GetMethod(nameof(ICollection <object> .Add), addMethodTypes); for (int i = 0; i < childElementCount; i++) { object deserializedElement = deserializeXmlElement(memberInfo, elementType, childElements[i], parentItem, arrayDimension + 1); if (isDictionary) { PersistAsAttribute persistData = getPersistDataForMember(memberInfo, null, arrayDimension + 1); if (persistData == null) { persistData = new PersistAsAttribute(UNDEFINED_ARRAY_ITEM_TAG); } object deserializedKey = childElements[i].GetAttribute(persistData.KeyAttribute); if (deserializedKey != null) { addMethod.Invoke(collection, new object[] { deserializedKey, deserializedElement }); } } else { addMethod.Invoke(collection, new object[] { deserializedElement }); } } return(collection); } return(null); }
private object deserializeXmlElement(MemberInfo memberInfo, Type memberType, XmlElement xmlElement, object parentItem, int arrayDimension = 0) { if (memberType == typeof(string)) { return(xmlElement.InnerText); } if ((xmlElement.InnerText == string.Empty) && PRIMITIVE_TYPES_NULL_IS_0.Contains(memberType)) { return(0); } bool isCollection = memberType.GetInterfaces().Any(interfaceType => interfaceType.IsGenericType && (interfaceType.GetGenericTypeDefinition() == typeof(ICollection <>))); if (memberType.IsArray || isCollection) { List <XmlElement> childElements = new List <XmlElement>(); foreach (XmlNode childNode in xmlElement.ChildNodes) { if (childNode.NodeType == XmlNodeType.Element) { childElements.Add((XmlElement)childNode); } } return(deserializeArray(memberInfo, memberType, childElements, parentItem, arrayDimension)); } if (memberType.IsEnum) { return(Enum.Parse(memberType, xmlElement.InnerText)); } Type nullableUnderlyingType = Nullable.GetUnderlyingType(memberType); if (nullableUnderlyingType?.IsEnum == true) { if (xmlElement.InnerText == string.Empty) { return(null); } return(Enum.Parse(nullableUnderlyingType, xmlElement.InnerText)); } Type deserializeAsType = memberType; if (Type.GetTypeCode(memberType) == TypeCode.Object) { PersistSubclassAttribute persistSubclassAttribute = memberInfo.GetCustomAttributes <PersistSubclassAttribute>().FirstOrDefault(); if (persistSubclassAttribute != null) // should check if given type is subclass of member type { deserializeAsType = persistSubclassAttribute.SubclassType; } PolymorphFieldAttribute polymorphFieldAttribute = memberInfo.GetCustomAttributes <PolymorphFieldAttribute>().FirstOrDefault(); Dictionary <Type, string> typeStringDictionary = null; if (polymorphFieldAttribute != null) { string itemTypeString = xmlElement.GetAttribute(polymorphFieldAttribute.TypeAttributeName); MethodInfo typeStringDictionaryGetterMethodInfo = parentItem.GetType().GetMethod(polymorphFieldAttribute.TypeStringDictionaryGetterName, memberLookupBindingFlags); typeStringDictionary = typeStringDictionaryGetterMethodInfo.Invoke(parentItem, new object[] { }) as Dictionary <Type, string>; KeyValuePair <Type, string> foundTypeData = typeStringDictionary.FirstOrDefault(kvp => (kvp.Value == itemTypeString)); if (foundTypeData.Key != null) { deserializeAsType = foundTypeData.Key; } } IValueXmlSerializer serializer = GetSerializerForType(deserializeAsType); if (serializer == null) { return(xmlElement.InnerText); } PersistAsAttribute persistData = getPersistDataForMember(memberInfo, null, arrayDimension); XmlElement itemToDeserialize = xmlElement; if (persistData.TagName != null) { itemToDeserialize = itemToDeserialize.OfType <XmlElement>().FirstOrDefault(); } return(serializer.DeserializeItem(itemToDeserialize, parentItem)); } return(Convert.ChangeType(xmlElement.InnerText, deserializeAsType)); }