/// <summary> /// Convert object to MetadataModel instance. /// </summary> /// <param name="source">Object to convert.</param> /// <param name="sourceType">The type of source object.</param> /// <param name="name">Name for result MetadataModel.</param> /// <returns>Instance of MetadataModel.</returns> public static MetadataModel ToMetadataModel(this object source, Type sourceType, string name = null) { if (source == null) { return(MetadataModel.GetEmptyMetadataModel()); } if (sourceType.Equals(typeof(MetadataModel))) { return((source as MetadataModel) ?? MetadataModel.GetEmptyMetadataModel()); } MetadataModel result = new MetadataModel { Name = name ?? sourceType.FullName.Replace('.', '_') }; if (XmlConverter.CanConvert(sourceType)) { result.IsValueType = true; try { result.Value = XmlConverter.ToString(source); } catch { result.Value = null; } } else if (source is XmlElement) { result.IsValueType = true; try { result.Value = (source as XmlElement).OuterXml; } catch { result.Value = null; } } else { result.IsValueType = false; if (CanEnumerable(sourceType)) { if (source != null) { foreach (var item in source as IEnumerable) { result.AddProperty(item.ToMetadataModel(item.GetType())); } } else { Type elementType = null; if (IsDictionary(sourceType)) { elementType = typeof(KeyValuePair <,>).MakeGenericType(sourceType.GetGenericArguments()); } else { elementType = sourceType.IsArray ? sourceType.GetElementType() : sourceType.GetGenericArguments()[0]; } result.AddProperty(((object)null).ToMetadataModel(elementType)); } } else { foreach (var item in sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead)) { try { object itemValue = source == null ? null : item.GetValue(source, null); result.AddProperty(itemValue.ToMetadataModel(item.PropertyType, item.Name)); } catch { } } } } return(result); }
/// <summary> /// Gets the property names internal. /// </summary> /// <param name="source">The source.</param> /// <param name="propertyAccess">The property access.</param> /// <param name="propertyName">Name of the property.</param> /// <returns>List of properties.</returns> private static List <KeyValuePair <string, Type> > GetPropertyNamesInternal(Type source, Func <PropertyInfo, bool> propertyAccess, string propertyName = null) { List <KeyValuePair <string, Type> > result = new List <KeyValuePair <string, Type> >(); if (source == typeof(void) || XmlConverter.CanConvert(source) || source == typeof(XmlElement)) { if (!string.IsNullOrWhiteSpace(propertyName)) { result.Add(new KeyValuePair <string, Type>(propertyName, source)); } return(result); } else { if (CanEnumerable(source)) { Type elementType = source.IsArray ? source.GetElementType() : source.GetGenericArguments()[0]; result.AddRange(GetPropertyNamesInternal(elementType, propertyAccess, propertyName + "[0]")); } else { foreach (var item in source.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(propertyAccess)) { Type type = item.PropertyType; if (type == source) { continue; } else if (CanEnumerable(type)) { Type elementType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; if (elementType == source) { continue; } } string name; if (string.IsNullOrWhiteSpace(propertyName)) { name = item.Name; } else { name = propertyName + "." + item.Name; } result.AddRange(GetPropertyNamesInternal(type, propertyAccess, name)); } } } return(result); }
/// <summary> /// Convert MetadataModel instance to object. /// </summary> /// <param name="source">MetadataModel to convert.</param> /// <param name="targetType">The type of return object.</param> /// <returns>The target type object.</returns> public static object ToObject(this MetadataModel source, Type targetType) { if (source.IsNull) { return(null); } if (targetType.Equals(typeof(MetadataModel))) { return(source); } if (XmlConverter.CanConvert(targetType)) { if (source.IsValueType && source.Value != null) { return(XmlConverter.ToObject(source.Value, targetType)); } else { return(null); } } else if (targetType.Equals(typeof(XmlElement))) { if (source.IsValueType && source.Value != null) { try { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(source.Value); return(xmlDocument.DocumentElement); } catch { return(null); } } else { return(null); } } else { if (CanEnumerable(targetType)) { if (IsDictionary(targetType)) { IDictionary propertyDict = (IDictionary)Activator.CreateInstance(targetType, true); foreach (var propertyItem in source.Properties) { if (!propertyItem.IsNull) { try { var key = propertyItem[0].ToObject(targetType.GetGenericArguments()[0]); if (key != null) { var value = propertyItem[1].ToObject(targetType.GetGenericArguments()[1]); propertyDict.Add(key, value); } } catch { } } } return(propertyDict.Count > 0 ? propertyDict : (IDictionary)null); } else { if (targetType.IsArray) { Type elementType = targetType.GetElementType(); IList resultTemp = new List <dynamic>(); foreach (var propertyItem in source.Properties) { if (!propertyItem.IsNull) { try { var listItem = propertyItem.ToObject(elementType); if (listItem != null) { resultTemp.Add(listItem); } } catch { } } } if (resultTemp.Count > 0) { Array result = Array.CreateInstance(elementType, resultTemp.Count); resultTemp.CopyTo(result, 0); return(result); } else { return((IList)null); } } else { Type elementType = targetType.GetGenericArguments()[0]; IList result = (IList)Activator.CreateInstance(targetType, true); foreach (var propertyItem in source.Properties) { if (!propertyItem.IsNull) { try { var listItem = propertyItem.ToObject(elementType); if (listItem != null) { result.Add(listItem); } } catch { } } } return(result.Count > 0 ? result : (IList)null); } } } else { object result = null; try { result = Activator.CreateInstance(targetType, true); } catch { try { result = FormatterServices.GetUninitializedObject(targetType); } catch { } } if (result == null) { return(result); } bool isNullReturn = true; foreach (var item in targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(i => i.CanWrite)) { try { if (source.HasProperty(item.Name)) { var sourceItem = source.GetProperty(item.Name); var sourceItemValue = sourceItem.ToObject(item.PropertyType); item.SetValue(result, sourceItemValue, null); if (sourceItemValue != null) { isNullReturn = false; } } } catch { } } return(isNullReturn ? null : result); } } }