private object GetPropertyValue(IEdmTypeReference propertyType, object value, ODataResource root) { if (value == null) { return(value); } switch (propertyType.TypeKind()) { case EdmTypeKind.Complex: if (CustomConverters.HasObjectConverter(value.GetType())) { return(CustomConverters.Convert(value, value.GetType())); } return(CreateODataEntry(propertyType.FullName(), value.ToDictionary(), root)); case EdmTypeKind.Collection: var collection = propertyType.AsCollection(); return(new ODataCollectionValue() { TypeName = propertyType.FullName(), Items = ((IEnumerable)value).Cast <object>().Select(x => GetPropertyValue(collection.ElementType(), x, root)), }); case EdmTypeKind.Primitive: var mappedTypes = _typeMap.Where(x => x.Value == (propertyType.Definition as IEdmPrimitiveType).PrimitiveKind); if (mappedTypes.Any()) { foreach (var mappedType in mappedTypes) { if (Utils.TryConvert(value, mappedType.Key, out var result)) { return(result); } } throw new NotSupportedException($"Conversion is not supported from type {value.GetType()} to OData type {propertyType}"); } return(value); case EdmTypeKind.Enum: return(new ODataEnumValue(value.ToString())); case EdmTypeKind.Untyped: return(new ODataUntypedValue { RawValue = value.ToString() }); case EdmTypeKind.None: if (CustomConverters.HasObjectConverter(value.GetType())) { return(CustomConverters.Convert(value, value.GetType())); } throw new NotSupportedException($"Conversion is not supported from type {value.GetType()} to OData type {propertyType}"); default: return(value); } }
private static object ToObject(this IDictionary <string, object> source, ITypeCache typeCache, Type type, string dynamicPropertiesContainerName, bool dynamicObject) { if (typeCache == null) { throw new ArgumentNullException(nameof(typeCache)); } if (source == null) { return(null); } if (typeof(IDictionary <string, object>).IsTypeAssignableFrom(type)) { return(source); } if (type == typeof(ODataEntry)) { return(CreateODataEntry(source, typeCache, dynamicObject)); } // TODO: Should be a method on TypeCache if (CustomConverters.HasDictionaryConverter(type)) { return(CustomConverters.Convert(source, type)); } var instance = CreateInstance(type); IDictionary <string, object> dynamicProperties = null; if (!string.IsNullOrEmpty(dynamicPropertiesContainerName)) { dynamicProperties = CreateDynamicPropertiesContainer(type, typeCache, instance, dynamicPropertiesContainerName); } foreach (var item in source) { var property = FindMatchingProperty(type, typeCache, item); if (property != null && property.CanWrite) { if (item.Value != null) { property.SetValue(instance, ConvertValue(property.PropertyType, typeCache, item.Value), null); } } else { dynamicProperties?.Add(item.Key, item.Value); } } return(instance); }
private static object ToObject(this IDictionary <string, object> source, Type type, Func <object> instanceFactory, string dynamicPropertiesContainerName, bool dynamicObject) { if (source == null) { return(null); } if (typeof(IDictionary <string, object>).IsTypeAssignableFrom(type)) { return(source); } if (type == typeof(ODataEntry)) { return(CreateODataEntry(source, dynamicObject)); } if (CustomConverters.HasDictionaryConverter(type)) { return(CustomConverters.Convert(source, type)); } var instance = instanceFactory(); IDictionary <string, object> dynamicProperties = null; if (!string.IsNullOrEmpty(dynamicPropertiesContainerName)) { dynamicProperties = CreateDynamicPropertiesContainer(type, instance, dynamicPropertiesContainerName); } foreach (var item in source) { var property = FindMatchingProperty(type, item); if (property != null && property.CanWrite && !property.IsNotMapped()) { if (item.Value != null) { property.SetValue(instance, ConvertValue(property.PropertyType, item.Value), null); } } else if (dynamicProperties != null) { dynamicProperties.Add(item.Key, item.Value); } } return(instance); }
private object GetPropertyValue(IEdmTypeReference propertyType, object value) { if (value == null) { return(value); } switch (propertyType.TypeKind()) { case EdmTypeKind.Complex: if (CustomConverters.HasObjectConverter(value.GetType())) { return(CustomConverters.Convert(value, value.GetType())); } var complexTypeProperties = propertyType.AsComplex().StructuralProperties(); return(new ODataComplexValue { TypeName = propertyType.FullName(), Properties = value.ToDictionary() .Where(val => complexTypeProperties.Any(p => p.Name == val.Key)) .Select(x => new ODataProperty { Name = x.Key, Value = GetPropertyValue(complexTypeProperties, x.Key, x.Value), }) }); case EdmTypeKind.Collection: var collection = propertyType.AsCollection(); return(new ODataCollectionValue() { TypeName = propertyType.FullName(), Items = ((IEnumerable)value).Cast <object>().Select(x => GetPropertyValue(collection.ElementType(), x)), }); case EdmTypeKind.Primitive: var mappedTypes = _typeMap.Where(x => x.Value == (propertyType.Definition as IEdmPrimitiveType).PrimitiveKind); if (mappedTypes.Any()) { foreach (var mappedType in mappedTypes) { object result; if (Utils.TryConvert(value, mappedType.Key, out result)) { return(result); } } throw new NotSupportedException(string.Format("Conversion is not supported from type {0} to OData type {1}", value.GetType(), propertyType)); } return(value); case EdmTypeKind.Enum: return(value.ToString()); case EdmTypeKind.None: if (CustomConverters.HasObjectConverter(value.GetType())) { return(CustomConverters.Convert(value, value.GetType())); } throw new NotSupportedException(string.Format("Conversion is not supported from type {0} to OData type {1}", value.GetType(), propertyType)); default: return(value); } }
private static object ToObject(this IDictionary <string, object> source, Type type, Func <object> instanceFactory, bool dynamicObject) { if (source == null) { return(null); } if (typeof(IDictionary <string, object>).IsTypeAssignableFrom(type)) { return(source); } if (type == typeof(ODataEntry)) { return(CreateODataEntry(source, dynamicObject)); } if (CustomConverters.HasConverter(type)) { return(CustomConverters.Convert(source, type)); } var instance = instanceFactory(); Func <Type, bool> IsCompoundType = fieldOrPropertyType => !fieldOrPropertyType.IsValue() && !fieldOrPropertyType.IsArray && fieldOrPropertyType != typeof(string); Func <Type, object, bool> IsCollectionType = (fieldOrPropertyType, itemValue) => (fieldOrPropertyType.IsArray || fieldOrPropertyType.IsGeneric() && typeof(System.Collections.IEnumerable).IsTypeAssignableFrom(fieldOrPropertyType)) && (itemValue as System.Collections.IEnumerable) != null; Func <Type, object, object> ConvertEnum = (fieldOrPropertyType, itemValue) => { if (itemValue == null) { return(null); } var stringValue = itemValue.ToString(); int intValue; if (int.TryParse(stringValue, out intValue)) { object result; Utils.TryConvert(intValue, fieldOrPropertyType, out result); return(result); } else { return(Enum.Parse(fieldOrPropertyType, stringValue, false)); } }; Func <Type, object, object> ConvertSingle = (fieldOrPropertyType, itemValue) => IsCompoundType(fieldOrPropertyType) ? itemValue.ToDictionary().ToObject(fieldOrPropertyType) : fieldOrPropertyType.IsEnumType() ? ConvertEnum(fieldOrPropertyType, itemValue) : itemValue; Func <Type, object, object> ConvertCollection = (fieldOrPropertyType, itemValue) => { var elementType = fieldOrPropertyType.IsArray ? fieldOrPropertyType.GetElementType() : fieldOrPropertyType.IsGeneric() && fieldOrPropertyType.GetGenericTypeArguments().Length == 1 ? fieldOrPropertyType.GetGenericTypeArguments()[0] : null; if (elementType == null) { return(null); } var count = (itemValue as System.Collections.IEnumerable).Cast <object>().Count(); var arrayValue = Array.CreateInstance(elementType, count); count = 0; foreach (var item in (itemValue as System.Collections.IEnumerable)) { (arrayValue as Array).SetValue(ConvertSingle(elementType, item), count++); } if (fieldOrPropertyType.IsArray || fieldOrPropertyType.IsTypeAssignableFrom(arrayValue.GetType())) { return(arrayValue); } else { var typedef = typeof(IEnumerable <>); var enumerableType = typedef.MakeGenericType(elementType); var ctor = fieldOrPropertyType.GetDeclaredConstructors().FirstOrDefault( x => x.GetParameters().Length == 1 && x.GetParameters().First().ParameterType == enumerableType); return(ctor != null ? ctor.Invoke(new object[] { arrayValue }) : null); } }; Func <Type, object, object> ConvertValue = (fieldOrPropertyType, itemValue) => IsCollectionType(fieldOrPropertyType, itemValue) ? ConvertCollection(fieldOrPropertyType, itemValue) : ConvertSingle(fieldOrPropertyType, itemValue); foreach (var item in source) { if (item.Value != null) { var property = type.GetAnyProperty(item.Key) ?? type.GetAllProperties().FirstOrDefault(x => x.GetMappedName() == item.Key); if (property != null && property.CanWrite && !property.IsNotMapped()) { property.SetValue(instance, ConvertValue(property.PropertyType, item.Value), null); } } } return(instance); }