/// <summary> /// Gets the MetadataModel at the specified property name. /// </summary> /// <param name="propertyName">The property name of the MetadataModel to get.</param> /// <returns>The MetadataModel at the specified property name.</returns> public MetadataModel GetProperty(string propertyName) { if (!this.IsValueType) { if (string.IsNullOrWhiteSpace(propertyName)) { return(this); } if (!propertyName.Contains('.')) { if (!propertyName.EndsWith("]")) { return(this[propertyName]); } else { int propertyNameIndex = propertyName.LastIndexOf("["); string propertyIndexerName = propertyName.Substring(0, propertyNameIndex); int index = int.Parse(propertyName.Substring(propertyNameIndex, propertyName.Length - propertyNameIndex).Trim('[', ']')); return(this.GetProperty(propertyIndexerName)[index]); } } else { var propertyChain = propertyName.Trim().Split('.'); MetadataModel result = this; foreach (var item in propertyChain) { result = result.GetProperty(item); if (result == null) { break; } } return(result); } } else if (this.Name == propertyName) { return(this); } else { throw new InvalidOperationException(string.Format("This MetadataModel (Name: {0}) is a value type. Cannot access MetadataModel Properties.", this.Name ?? string.Empty)); } }
/// <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); } } }
/// <summary> /// Sets the MetadataModel at the specified property name. /// </summary> /// <param name="propertyName">The property name of the MetadataModel to set.</param> /// <param name="property">The instance of the property.</param> public void SetProperty(string propertyName, MetadataModel property) { if (!this.IsValueType) { if (!propertyName.Contains('.')) { if (!propertyName.EndsWith("]")) { this[propertyName] = property; } else { int propertyNameIndex = propertyName.LastIndexOf("["); string propertyIndexerName = propertyName.Substring(0, propertyNameIndex); int index = int.Parse(propertyName.Substring(propertyNameIndex, propertyName.Length - propertyNameIndex).Trim('[', ']')); MetadataModel result = this; try { if (result.Properties != null && result.Properties.Count > 0 && result.Properties.Any(p => p.Name.Equals(propertyIndexerName))) { result = result.GetProperty(propertyIndexerName); } else { result.SetProperty(propertyIndexerName, new MetadataModel { Name = propertyIndexerName, IsValueType = false }); result = result.GetProperty(propertyIndexerName); } } catch { result.SetProperty(propertyIndexerName, new MetadataModel { Name = propertyIndexerName, IsValueType = false }); result = result.GetProperty(propertyIndexerName); } result[index] = property; } } else { var propertyChain = propertyName.Trim().Split('.'); MetadataModel result = this; foreach (var item in propertyChain) { try { if (result.Properties != null && result.Properties.Count > 0) { string itemName = item; if (item.EndsWith("]")) { int itemNameIndex = item.LastIndexOf("["); string itemIndexerName = item.Substring(0, itemNameIndex); itemName = itemIndexerName; } if (result.Properties.Any(p => p.Name.Equals(itemName)) || itemName == string.Empty) { result = result.GetProperty(item); continue; } } result.SetProperty(item, new MetadataModel { Name = item, IsValueType = false }); result = result.GetProperty(item); } catch { result.SetProperty(item, new MetadataModel { Name = item, IsValueType = false }); result = result.GetProperty(item); } } result.CloneFrom(property); } } else if (this.Name == propertyName) { this.Value = property.Value; } else { throw new InvalidOperationException(string.Format("This MetadataModel (Name: {0}) is a value type. Cannot access MetadataModel Properties.", this.Name ?? string.Empty)); } }
/// <summary> /// Determines whether the MetadataModel has the specified property. /// </summary> /// <param name="propertyName">Name of the property.</param> /// <returns>true if the MetadataModel has the specified property; otherwise, false.</returns> public bool HasProperty(string propertyName) { if (!this.IsValueType) { if (!propertyName.Contains('.')) { if (this.Properties != null && this.Properties.Count > 0) { string itemName = propertyName; if (propertyName.EndsWith("]")) { int itemNameIndex = propertyName.LastIndexOf("["); string itemIndexerName = propertyName.Substring(0, itemNameIndex); itemName = itemIndexerName; } return(this.Properties.Any(p => p.Name.Equals(itemName))); } return(false); } else { var propertyChain = propertyName.Trim().Split('.'); MetadataModel result = this; foreach (var item in propertyChain) { try { if (result.Properties != null && result.Properties.Count > 0) { string itemName = item; if (item.EndsWith("]")) { int itemNameIndex = item.LastIndexOf("["); string itemIndexerName = item.Substring(0, itemNameIndex); itemName = itemIndexerName; } if (result.Properties.Any(p => p.Name.Equals(itemName))) { result = result.GetProperty(item); continue; } } return(false); } catch { return(false); } } return(true); } } else { throw new InvalidOperationException(string.Format("This MetadataModel (Name: {0}) is a value type. Cannot access MetadataModel Properties.", this.Name ?? string.Empty)); } }