internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmProperty edmProperty = resourceType.FindProperty(property.Name);

            string propertyName = property.Name;
            IEdmTypeReference propertyType = edmProperty != null ? edmProperty.Type : null; // open properties have null values

            // If we are in patch mode and we are deserializing an entity object then we are updating Delta<T> and not T.
            bool isDelta = readContext.IsPatchMode && resourceType.IsEntity();

            EdmTypeKind propertyKind;
            object value = ConvertValue(property.Value, ref propertyType, deserializerProvider, readContext, out propertyKind);

            if (propertyKind == EdmTypeKind.Collection)
            {
                SetCollectionProperty(resource, propertyName, isDelta, value);
            }
            else
            {
                if (propertyKind == EdmTypeKind.Primitive)
                {
                    value = EdmPrimitiveHelpers.ConvertPrimitiveValue(value, GetPropertyType(resource, propertyName, isDelta));
                }

                SetProperty(resource, propertyName, isDelta, value);
            }
        }
Exemplo n.º 2
0
        internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource,
            ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext, AssembliesResolver assembliesResolver)
        {
            IEdmProperty edmProperty = resourceType.FindProperty(property.Name);

            bool isDynamicProperty = false;
            string propertyName = property.Name;
            if (edmProperty != null)
            {
                propertyName = EdmLibHelpers.GetClrPropertyName(edmProperty, readContext.Model);
            }
            else
            {
                IEdmStructuredType structuredType = resourceType.StructuredDefinition();
                isDynamicProperty = structuredType != null && structuredType.IsOpen;
            }

            // dynamic properties have null values
            IEdmTypeReference propertyType = edmProperty != null ? edmProperty.Type : null;

            EdmTypeKind propertyKind;
            object value = ConvertValue(property.Value, ref propertyType, deserializerProvider, readContext,
                out propertyKind);

            if (isDynamicProperty)
            {
                SetDynamicProperty(resource, resourceType, propertyKind, propertyName, value, propertyType,
                    readContext, assembliesResolver);
            }
            else
            {
                SetDeclaredProperty(resource, propertyKind, propertyName, value, edmProperty, readContext, assembliesResolver);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
        /// </summary>
        /// <param name="instance">The backing CLR instance.</param>
        /// <param name="edmType">The <see cref="IEdmStructuredType"/> of this object.</param>
        public EdmStructuredObject(object instance, IEdmStructuredTypeReference edmType)
        {
            Contract.Assert(edmType != null);

            Instance = instance;
            EdmType = edmType;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmRecordExpression"/> class.
        /// </summary>
        /// <param name="declaredType">Optional declared type of the record.</param>
        /// <param name="properties">Property constructors.</param>
        public EdmRecordExpression(IEdmStructuredTypeReference declaredType, IEnumerable<IEdmPropertyConstructor> properties)
        {
            EdmUtil.CheckArgumentNull(properties, "properties");

            this.declaredType = declaredType;
            this.properties = properties;
        }
        internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource,
            ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmProperty edmProperty = resourceType.FindProperty(property.Name);

            string propertyName = property.Name;
            IEdmTypeReference propertyType = edmProperty != null ? edmProperty.Type : null; // open properties have null values

            EdmTypeKind propertyKind;
            object value = ConvertValue(property.Value, ref propertyType, deserializerProvider, readContext, out propertyKind);

            if (propertyKind == EdmTypeKind.Collection)
            {
                SetCollectionProperty(resource, edmProperty, value);
            }
            else
            {
                if (propertyKind == EdmTypeKind.Primitive && !readContext.IsUntyped)
                {
                    value = EdmPrimitiveHelpers.ConvertPrimitiveValue(value, GetPropertyType(resource, propertyName));
                }

                SetProperty(resource, propertyName, value);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TypedEdmStructuredObject"/> class.
        /// </summary>
        /// <param name="instance">The backing CLR instance.</param>
        /// <param name="edmType">The <see cref="IEdmStructuredType"/> of this object.</param>
        protected TypedEdmStructuredObject(object instance, IEdmStructuredTypeReference edmType)
        {
            Contract.Assert(edmType != null);

            Instance = instance;
            _edmType = edmType;
            _type = instance == null ? null : instance.GetType();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates a new Edm structured value from an OData complex value.
        /// </summary>
        /// <param name="complexValue">The <see cref="ODataComplexValue"/> to create the structured value for.</param>
        internal ODataEdmStructuredValue(ODataComplexValue complexValue)
            : base(complexValue.GetEdmType())
        {
            Debug.Assert(complexValue != null, "complexValue != null");

            this.properties = complexValue.Properties;
            this.structuredType = this.Type == null ? null : this.Type.AsStructured();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Creates a new Edm structured value from an OData entry.
        /// </summary>
        /// <param name="entry">The <see cref="ODataEntry"/> to create the structured value for.</param>
        internal ODataEdmStructuredValue(ODataEntry entry)
            : base(entry.GetEdmType())
        {
            Debug.Assert(entry != null, "entry != null");

            this.properties = entry.NonComputedProperties;
            this.structuredType = this.Type == null ? null : this.Type.AsStructured();
        }
        internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource,
            ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmProperty edmProperty = resourceType.FindProperty(property.Name);

            // try to deserializer the dynamic properties for open type.
            if (edmProperty == null)
            {
                // the logic here works for open complex type and open entity type.
                IEdmStructuredType structuredType = resourceType.StructuredDefinition();
                if (structuredType != null && structuredType.IsOpen)
                {
                    if (ApplyDynamicProperty(property, structuredType, resource, deserializerProvider, readContext))
                    {
                        return;
                    }
                }
            }

            string propertyName = property.Name;
            if (edmProperty != null)
            {
                propertyName = EdmLibHelpers.GetClrPropertyName(edmProperty, readContext.Model);
            }
            IEdmTypeReference propertyType = edmProperty != null ? edmProperty.Type : null; // open properties have null values

            EdmTypeKind propertyKind;
            object value = ConvertValue(property.Value, ref propertyType, deserializerProvider, readContext, out propertyKind);

            if (propertyKind == EdmTypeKind.Collection)
            {
                SetCollectionProperty(resource, edmProperty, value, propertyName);
            }
            else
            {
                if (!readContext.IsUntyped)
                {
                    if (propertyKind == EdmTypeKind.Primitive)
                    {
                        value = EdmPrimitiveHelpers.ConvertPrimitiveValue(value, GetPropertyType(resource, propertyName));
                    }
                    else if (propertyKind == EdmTypeKind.Enum)
                    {
                        value = EnumDeserializationHelpers.ConvertEnumValue(value, GetPropertyType(resource, propertyName));
                    }
                }

                SetProperty(resource, propertyName, value);
            }
        }
Exemplo n.º 10
0
 internal static void SetDynamicProperty(object resource, IEdmStructuredTypeReference resourceType,
     EdmTypeKind propertyKind, string propertyName, object propertyValue, IEdmTypeReference propertyType,
     ODataDeserializerContext readContext, AssembliesResolver assembliesResolver)
 {  
     if (propertyKind == EdmTypeKind.Collection && propertyValue.GetType() != typeof(EdmComplexObjectCollection)
         && propertyValue.GetType() != typeof(EdmEnumObjectCollection))
     {
         SetDynamicCollectionProperty(resource, propertyName, propertyValue, propertyType.AsCollection(),
             resourceType.StructuredDefinition(), readContext, assembliesResolver);
     }
     else
     {
         SetDynamicProperty(resource, propertyName, propertyValue, resourceType.StructuredDefinition(),
             readContext);
     }
 }
Exemplo n.º 11
0
        /// <summary>
        /// Converts an <see cref="ODataProperty"/> into the corresponding <see cref="IEdmPropertyValue"/>.
        /// </summary>
        /// <param name="property">The non-null <see cref="ODataProperty"/> to convert.</param>
        /// <param name="declaringType">The declaring type of the property.</param>
        /// <returns>An <see cref="IEdmPropertyValue"/> implementation of the <paramref name="property"/> value.</returns>
        internal static IEdmPropertyValue GetEdmPropertyValue(this ODataProperty property, IEdmStructuredTypeReference declaringType)
        {
            Debug.Assert(property != null, "property != null");

            IEdmTypeReference propertyType = null;
            if (declaringType != null)
            {
                IEdmProperty edmProperty = declaringType.FindProperty(property.Name);
                if (edmProperty == null && !declaringType.IsOpen())
                {
                    throw new ODataException(ODataErrorStrings.ODataEdmStructuredValue_UndeclaredProperty(property.Name, declaringType.FullName()));
                }

                propertyType = edmProperty == null ? null : edmProperty.Type;
            }

            return new EdmPropertyValue(property.Name, ConvertValue(property.Value, propertyType).Value);
        }
Exemplo n.º 12
0
		public EdmStructuredValue(IEdmStructuredTypeReference type, IEnumerable<IEdmPropertyValue> propertyValues) : base(type)
		{
			EdmUtil.CheckArgumentNull<IEnumerable<IEdmPropertyValue>>(propertyValues, "propertyValues");
			this.propertyValues = propertyValues;
			if (propertyValues != null)
			{
				int num = 0;
				foreach (IEdmPropertyValue propertyValue in propertyValues)
				{
					num++;
					if (num <= 5)
					{
						continue;
					}
					this.propertiesDictionaryCache = new Cache<EdmStructuredValue, Dictionary<string, IEdmPropertyValue>>();
					break;
				}
			}
		}
        internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerReadContext readContext)
        {
            IEdmProperty edmProperty = resourceType.FindProperty(property.Name);

            string propertyName = property.Name;
            IEdmTypeReference propertyType = edmProperty != null ? edmProperty.Type : null; // open properties have null values

            object value = ConvertValue(property.Value, ref propertyType, deserializerProvider, readContext);

            // If we are in patch mode and we are deserializing an entity object then we are updating Delta<T> and not T.
            if (!readContext.IsPatchMode || !resourceType.IsEntity())
            {
                resource.GetType().GetProperty(propertyName).SetValue(resource, value, index: null);
            }
            else
            {
                (resource as IDelta).TrySetPropertyValue(propertyName, value);
            }
        }
        internal static void SetDynamicProperty(object resource, IEdmStructuredTypeReference resourceType,
            EdmTypeKind propertyKind, string propertyName, object propertyValue, IEdmTypeReference propertyType,
            ODataDeserializerContext readContext)
        {
            if (propertyKind == EdmTypeKind.Collection)
            {
                SetDynamicCollectionProperty(resource, propertyName, propertyValue, propertyType.AsCollection(),
                    resourceType.StructuredDefinition(), readContext);
            }
            else
            {
                if (propertyKind == EdmTypeKind.Enum)
                {
                    propertyValue = ConvertDynamicEnumValue(propertyValue, readContext);
                }

                SetDynamicProperty(resource, propertyName, propertyValue, resourceType.StructuredDefinition(),
                    readContext);
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmStructuredValue"/> class.
        /// </summary>
        /// <param name="type">Type that describes this value.</param>
        /// <param name="propertyValues">Child values of this value.</param>
        public EdmStructuredValue(IEdmStructuredTypeReference type, IEnumerable<IEdmPropertyValue> propertyValues)
            : base(type)
        {
            EdmUtil.CheckArgumentNull(propertyValues, "propertyValues");

            this.propertyValues = propertyValues;
            if (propertyValues != null)
            {
                // If there are enough property values, make FindPropertyValue use a dictionary.
                int propertyCount = 0;
                foreach (IEdmPropertyValue propertyValue in propertyValues)
                {
                    propertyCount++;
                    if (propertyCount > 5)
                    {
                        this.propertiesDictionaryCache = new Cache<EdmStructuredValue, Dictionary<string, IEdmPropertyValue>>();
                        break;
                    }
                }
            }
        }
        internal static Func<object, object> GetOrCreatePropertyGetter(
            Type type,
            string propertyName,
            IEdmStructuredTypeReference edmType,
            IEdmModel model)
        {
            Tuple<string, Type> key = Tuple.Create(propertyName, type);
            Func<object, object> getter;

            if (!_propertyGetterCache.TryGetValue(key, out getter))
            {
                IEdmProperty property = edmType.FindProperty(propertyName);
                if (property != null && model != null)
                {
                    propertyName = EdmLibHelpers.GetClrPropertyName(property, model) ?? propertyName;
                }

                getter = CreatePropertyGetter(type, propertyName);
                _propertyGetterCache[key] = getter;
            }

            return getter;
        }
Exemplo n.º 17
0
        private void SetEpmValueForSegment(EntityPropertyMappingInfo epmInfo, int propertyValuePathIndex, IEdmStructuredTypeReference segmentStructuralTypeReference, List<ODataProperty> existingProperties, object propertyValue)
        {
            string propertyName = epmInfo.PropertyValuePath[propertyValuePathIndex].PropertyName;
            if (!epmInfo.Attribute.KeepInContent)
            {
                IEdmTypeReference type;
                ODataProperty property = existingProperties.FirstOrDefault<ODataProperty>(p => string.CompareOrdinal(p.Name, propertyName) == 0);
                ODataComplexValue value2 = null;
                if (property != null)
                {
                    value2 = property.Value as ODataComplexValue;
                    if (value2 == null)
                    {
                        return;
                    }
                }
                IEdmProperty property2 = segmentStructuralTypeReference.FindProperty(propertyName);
                if ((property2 == null) && (propertyValuePathIndex != (epmInfo.PropertyValuePath.Length - 1)))
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.EpmReader_OpenComplexOrCollectionEpmProperty(epmInfo.Attribute.SourcePath));
                }
                if ((property2 == null) || (this.MessageReaderSettings.DisablePrimitiveTypeConversion && property2.Type.IsODataPrimitiveTypeKind()))
                {
                    type = EdmCoreModel.Instance.GetString(true);
                }
                else
                {
                    type = property2.Type;
                }
                switch (type.TypeKind())
                {
                    case EdmTypeKind.Primitive:
                        object obj2;
                        if (type.IsStream())
                        {
                            throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmReader_SetEpmValueForSegment_StreamProperty));
                        }
                        if (propertyValue == null)
                        {
                            ReaderValidationUtils.ValidateNullValue(this.atomInputContext.Model, type, this.atomInputContext.MessageReaderSettings, true, this.atomInputContext.Version);
                            obj2 = null;
                        }
                        else
                        {
                            obj2 = AtomValueUtils.ConvertStringToPrimitive((string) propertyValue, type.AsPrimitive());
                        }
                        this.AddEpmPropertyValue(existingProperties, propertyName, obj2, segmentStructuralTypeReference.IsODataEntityTypeKind());
                        return;

                    case EdmTypeKind.Complex:
                    {
                        if (value2 == null)
                        {
                            value2 = new ODataComplexValue {
                                TypeName = type.ODataFullName(),
                                Properties = new ReadOnlyEnumerable<ODataProperty>()
                            };
                            this.AddEpmPropertyValue(existingProperties, propertyName, value2, segmentStructuralTypeReference.IsODataEntityTypeKind());
                        }
                        IEdmComplexTypeReference reference2 = type.AsComplex();
                        this.SetEpmValueForSegment(epmInfo, propertyValuePathIndex + 1, reference2, ReaderUtils.GetPropertiesList(value2.Properties), propertyValue);
                        return;
                    }
                    case EdmTypeKind.Collection:
                    {
                        ODataCollectionValue value4 = new ODataCollectionValue {
                            TypeName = type.ODataFullName(),
                            Items = new ReadOnlyEnumerable((List<object>) propertyValue)
                        };
                        this.AddEpmPropertyValue(existingProperties, propertyName, value4, segmentStructuralTypeReference.IsODataEntityTypeKind());
                        return;
                    }
                }
                throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmReader_SetEpmValueForSegment_TypeKind));
            }
        }
Exemplo n.º 18
0
        internal static bool TryAssertRecordAsType(this IEdmRecordExpression expression, IEdmTypeReference type, out IEnumerable <EdmError> discoveredErrors)
        {
            IEnumerable <EdmError> edmErrors = null;

            EdmUtil.CheckArgumentNull <IEdmRecordExpression>(expression, "expression");
            EdmUtil.CheckArgumentNull <IEdmTypeReference>(type, "type");
            if (type.IsStructured())
            {
                HashSetInternal <string>    strs       = new HashSetInternal <string>();
                List <EdmError>             edmErrors1 = new List <EdmError>();
                IEdmStructuredTypeReference edmStructuredTypeReference = type.AsStructured();
                IEnumerator <IEdmProperty>  enumerator = edmStructuredTypeReference.StructuredDefinition().Properties().GetEnumerator();
                using (enumerator)
                {
                    Func <IEdmPropertyConstructor, bool> func = null;
                    while (enumerator.MoveNext())
                    {
                        IEdmProperty current = enumerator.Current;
                        IEnumerable <IEdmPropertyConstructor> properties = expression.Properties;
                        if (func == null)
                        {
                            func = (IEdmPropertyConstructor p) => p.Name == current.Name;
                        }
                        IEdmPropertyConstructor edmPropertyConstructor = properties.FirstOrDefault <IEdmPropertyConstructor>(func);
                        if (edmPropertyConstructor != null)
                        {
                            if (!edmPropertyConstructor.Value.TryAssertType(current.Type, out edmErrors))
                            {
                                IEnumerator <EdmError> enumerator1 = edmErrors.GetEnumerator();
                                using (enumerator1)
                                {
                                    while (enumerator1.MoveNext())
                                    {
                                        EdmError edmError = enumerator1.Current;
                                        edmErrors1.Add(edmError);
                                    }
                                }
                            }
                            strs.Add(current.Name);
                        }
                        else
                        {
                            edmErrors1.Add(new EdmError(expression.Location(), EdmErrorCode.RecordExpressionMissingRequiredProperty, Strings.EdmModel_Validator_Semantic_RecordExpressionMissingProperty(current.Name)));
                        }
                    }
                }
                if (!edmStructuredTypeReference.IsOpen())
                {
                    foreach (IEdmPropertyConstructor property in expression.Properties)
                    {
                        if (strs.Contains(property.Name))
                        {
                            continue;
                        }
                        edmErrors1.Add(new EdmError(expression.Location(), EdmErrorCode.RecordExpressionHasExtraProperties, Strings.EdmModel_Validator_Semantic_RecordExpressionHasExtraProperties(property.Name)));
                    }
                }
                if (edmErrors1.FirstOrDefault <EdmError>() == null)
                {
                    discoveredErrors = Enumerable.Empty <EdmError>();
                    return(true);
                }
                else
                {
                    discoveredErrors = edmErrors1;
                    return(false);
                }
            }
            else
            {
                EdmError[] edmErrorArray = new EdmError[1];
                edmErrorArray[0] = new EdmError(expression.Location(), EdmErrorCode.RecordExpressionNotValidForNonStructuredType, Strings.EdmModel_Validator_Semantic_RecordExpressionNotValidForNonStructuredType);
                discoveredErrors = edmErrorArray;
                return(false);
            }
        }
Exemplo n.º 19
0
        private void ApplyDynamicResourceInNestedProperty(string propertyName, object resource, IEdmStructuredTypeReference resourceStructuredType,
                                                          ODataResourceWrapper resourceWrapper, ODataDeserializerContext readContext)
        {
            Contract.Assert(resource != null);
            Contract.Assert(readContext != null);

            object value = null;

            if (resourceWrapper != null)
            {
                IEdmSchemaType    elementType      = readContext.Model.FindDeclaredType(resourceWrapper.Resource.TypeName);
                IEdmTypeReference edmTypeReference = elementType.ToEdmTypeReference(true);

                value = ReadNestedResourceInline(resourceWrapper, edmTypeReference, readContext);
            }

            DeserializationHelpers.SetDynamicProperty(resource, propertyName, value,
                                                      resourceStructuredType.StructuredDefinition(), readContext.Model);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Converts an <see cref="ODataProperty"/> into the corresponding <see cref="IEdmPropertyValue"/>.
        /// </summary>
        /// <param name="property">The non-null <see cref="ODataProperty"/> to convert.</param>
        /// <param name="declaringType">The declaring type of the property.</param>
        /// <returns>An <see cref="IEdmPropertyValue"/> implementation of the <paramref name="property"/> value.</returns>
        internal static IEdmPropertyValue GetEdmPropertyValue(this ODataProperty property, IEdmStructuredTypeReference declaringType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(property != null, "property != null");

            IEdmTypeReference propertyType = null;

            if (declaringType != null)
            {
                IEdmProperty edmProperty = declaringType.FindProperty(property.Name);
                if (edmProperty == null && !declaringType.IsOpen())
                {
                    throw new ODataException(ODataErrorStrings.ODataEdmStructuredValue_UndeclaredProperty(property.Name, declaringType.FullName()));
                }

                propertyType = edmProperty == null ? null : edmProperty.Type;
            }

            return(new EdmPropertyValue(property.Name, ConvertValue(property.Value, propertyType).Value));
        }
Exemplo n.º 21
0
        /// <summary>
        /// Deserializes the given <paramref name="resourceWrapper"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="resourceWrapper">The OData resource to deserialize.</param>
        /// <param name="structuredType">The type of the resource to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized resource.</returns>
        public virtual object ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType,
                                           ODataDeserializerContext readContext)
        {
            if (resourceWrapper == null)
            {
                throw new ArgumentNullException(nameof(resourceWrapper));
            }

            if (readContext == null)
            {
                throw new ArgumentNullException(nameof(readContext));
            }

            if (!String.IsNullOrEmpty(resourceWrapper.Resource.TypeName) && structuredType.FullName() != resourceWrapper.Resource.TypeName)
            {
                // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer.
                IEdmModel model = readContext.Model;

                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType;
                if (actualType == null)
                {
                    throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName));
                }

                if (actualType.IsAbstract)
                {
                    string message = Error.Format(SRResources.CannotInstantiateAbstractResourceType, resourceWrapper.Resource.TypeName);
                    throw new ODataException(message);
                }

                IEdmTypeReference actualStructuredType;
                IEdmEntityType    actualEntityType = actualType as IEdmEntityType;
                if (actualEntityType != null)
                {
                    actualStructuredType = new EdmEntityTypeReference(actualEntityType, isNullable: false);
                }
                else
                {
                    actualStructuredType = new EdmComplexTypeReference(actualType as IEdmComplexType, isNullable: false);
                }

                ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(actualStructuredType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName()));
                }

                object resource = deserializer.ReadInline(resourceWrapper, actualStructuredType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = structuredType.StructuredDefinition();
                }

                return(resource);
            }
            else
            {
                object resource = CreateResourceInstance(structuredType, readContext);
                ApplyResourceProperties(resource, resourceWrapper, structuredType, readContext);
                return(resource);
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Deserializes the nested property from <paramref name="resourceInfoWrapper"/> into <paramref name="resource"/>.
        /// </summary>
        /// <param name="resource">The object into which the nested property should be read.</param>
        /// <param name="resourceInfoWrapper">The nested resource info.</param>
        /// <param name="structuredType">The type of the resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfoWrapper resourceInfoWrapper,
                                                IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            if (resourceInfoWrapper == null)
            {
                throw new ArgumentNullException(nameof(resourceInfoWrapper));
            }

            IEdmProperty edmProperty = structuredType.FindProperty(resourceInfoWrapper.NestedResourceInfo.Name);

            if (edmProperty == null)
            {
                if (!structuredType.IsOpen())
                {
                    throw new ODataException(
                              Error.Format(SRResources.NestedPropertyNotfound, resourceInfoWrapper.NestedResourceInfo.Name,
                                           structuredType.FullName()));
                }
            }

            foreach (ODataItemBase childItem in resourceInfoWrapper.NestedItems)
            {
                // it maybe null.
                if (childItem == null)
                {
                    if (edmProperty == null)
                    {
                        // for the dynamic, OData.net has a bug. see https://github.com/OData/odata.net/issues/977
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, null, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, null, readContext);
                    }
                }

                ODataEntityReferenceLinkBase entityReferenceLink = childItem as ODataEntityReferenceLinkBase;
                if (entityReferenceLink != null)
                {
                    // ignore entity reference links.
                    continue;
                }

                ODataResourceSetWrapper resourceSetWrapper = childItem as ODataResourceSetWrapper;
                if (resourceSetWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceSetInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name,
                                                                resource, structuredType, resourceSetWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceSetInNestedProperty(edmProperty, resource, resourceSetWrapper, readContext);
                    }

                    continue;
                }

                // It must be resource by now.
                ODataResourceWrapper resourceWrapper = (ODataResourceWrapper)childItem;
                if (resourceWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, resourceWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, resourceWrapper, readContext);
                    }
                }
            }
        }
Exemplo n.º 23
0
 public TestEdmStructuredObject(IEdmStructuredTypeReference edmType)
     : base(edmType)
 {
 }
Exemplo n.º 24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmRecordExpression"/> class.
 /// </summary>
 /// <param name="declaredType">Declared type of the record.</param>
 /// <param name="properties">Property constructors.</param>
 public EdmRecordExpression(IEdmStructuredTypeReference declaredType, params IEdmPropertyConstructor[] properties)
     : this(declaredType, (IEnumerable <IEdmPropertyConstructor>)properties)
 {
 }
Exemplo n.º 25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmRecordExpression"/> class.
 /// </summary>
 /// <param name="declaredType">Declared type of the record.</param>
 /// <param name="properties">Property constructors.</param>
 public EdmRecordExpression(IEdmStructuredTypeReference declaredType, params IEdmPropertyConstructor[] properties)
     : this(declaredType, (IEnumerable<IEdmPropertyConstructor>)properties)
 {
 }
Exemplo n.º 26
0
        private ODataResourceSet GetResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, IEdmStructuredTypeReference elementType,
                                                ODataSerializerContext writeContext)
        {
            ODataResourceSet resourceSet = CreateResourceSet(enumerable, resourceSetType.AsCollection(), writeContext);

            if (resourceSet == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                resourceSet.SetSerializationInfo(new ODataResourceSerializationInfo
                {
                    IsFromCollection = true,
                    NavigationSourceEntityTypeName = elementType.FullName(),
                    NavigationSourceKind           = EdmNavigationSourceKind.UnknownEntitySet,
                    NavigationSourceName           = null
                });
            }

            return(resourceSet);
        }
Exemplo n.º 27
0
 protected virtual void ProcessStructuredTypeReference(IEdmStructuredTypeReference reference)
 {
     this.ProcessTypeReference(reference);
 }
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
                               ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            IEdmStructuredTypeReference elementType = GetResourceType(feedType);

            if (elementType.IsComplex())
            {
                ODataResourceSet resourceSet = new ODataResourceSet()
                {
                    TypeName = feedType.FullName()
                };

                writer.WriteStart(resourceSet);

                ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataResourceSerializer;
                if (entrySerializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName()));
                }

                foreach (object entry in enumerable)
                {
                    entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext);
                }
            }
            else
            {
                ODataDeltaResourceSet deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext);
                if (deltaFeed == null)
                {
                    throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
                }

                // save the next page link for later to support JSON odata.streaming.
                Func <object, Uri> nextLinkGenerator = GetNextLinkGenerator(deltaFeed, enumerable, writeContext);
                deltaFeed.NextPageLink = null;

                //Start writing of the Delta Feed
                writer.WriteStart(deltaFeed);

                object lastResource = null;
                //Iterate over all the entries present and select the appropriate write method.
                //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry.
                foreach (object entry in enumerable)
                {
                    if (entry == null)
                    {
                        throw new SerializationException(SRResources.NullElementInCollection);
                    }

                    lastResource = entry;
                    IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
                    if (edmChangedObject == null)
                    {
                        throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
                    }

                    switch (edmChangedObject.DeltaKind)
                    {
                    case EdmDeltaEntityKind.DeletedEntry:
                        WriteDeltaDeletedEntry(entry, writer, writeContext);
                        break;

                    case EdmDeltaEntityKind.DeletedLinkEntry:
                        WriteDeltaDeletedLink(entry, writer, writeContext);
                        break;

                    case EdmDeltaEntityKind.LinkEntry:
                        WriteDeltaLink(entry, writer, writeContext);
                        break;

                    case EdmDeltaEntityKind.Entry:
                    {
                        ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataResourceSerializer;
                        if (entrySerializer == null)
                        {
                            throw new SerializationException(
                                      Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName()));
                        }
                        entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext);
                        break;
                    }

                    default:
                        break;
                    }
                }

                // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
                // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
                // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
                // object before calling WriteEnd(), the next page link will be written at the end, as required for
                // odata.streaming=true support.

                deltaFeed.NextPageLink = nextLinkGenerator(lastResource);
            }

            //End Writing of the Delta Feed
            writer.WriteEnd();
        }
Exemplo n.º 29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmStructuredTypeReference"/> of this object.</param>
 protected EdmStructuredObject(IEdmStructuredTypeReference edmType)
     : this(edmType.StructuredDefinition(), edmType.IsNullable)
 {
 }
Exemplo n.º 30
0
        private static bool AssertOrMatchStructuredType(IEdmStructuredTypeReference structuredTargetType, IEdmStructuredValue structuredValue, bool testPropertyTypes, List <IEdmPropertyValue> newProperties)
        {
            bool flag;
            IEdmTypeReference type = structuredValue.Type;

            if (type == null || type.TypeKind() == EdmTypeKind.Row || structuredTargetType.StructuredDefinition().InheritsFrom(type.AsStructured().StructuredDefinition()))
            {
                HashSetInternal <IEdmPropertyValue>  edmPropertyValues = new HashSetInternal <IEdmPropertyValue>();
                IEnumerator <IEdmStructuralProperty> enumerator        = structuredTargetType.StructuralProperties().GetEnumerator();
                using (enumerator)
                {
                    while (enumerator.MoveNext())
                    {
                        IEdmProperty      current          = enumerator.Current;
                        IEdmPropertyValue edmPropertyValue = structuredValue.FindPropertyValue(current.Name);
                        if (edmPropertyValue != null)
                        {
                            edmPropertyValues.Add(edmPropertyValue);
                            if (!testPropertyTypes)
                            {
                                continue;
                            }
                            if (newProperties == null)
                            {
                                if (EdmExpressionEvaluator.MatchesType(current.Type, edmPropertyValue.Value))
                                {
                                    continue;
                                }
                                flag = false;
                                return(flag);
                            }
                            else
                            {
                                newProperties.Add(new EdmPropertyValue(edmPropertyValue.Name, EdmExpressionEvaluator.AssertType(current.Type, edmPropertyValue.Value)));
                            }
                        }
                        else
                        {
                            flag = false;
                            return(flag);
                        }
                    }
                    if (structuredTargetType.IsEntity())
                    {
                        IEnumerator <IEdmNavigationProperty> enumerator1 = structuredTargetType.AsEntity().NavigationProperties().GetEnumerator();
                        using (enumerator1)
                        {
                            while (enumerator1.MoveNext())
                            {
                                IEdmNavigationProperty edmNavigationProperty = enumerator1.Current;
                                IEdmPropertyValue      edmPropertyValue1     = structuredValue.FindPropertyValue(edmNavigationProperty.Name);
                                if (edmPropertyValue1 != null)
                                {
                                    if (!testPropertyTypes || EdmExpressionEvaluator.MatchesType(edmNavigationProperty.Type, edmPropertyValue1.Value, false))
                                    {
                                        edmPropertyValues.Add(edmPropertyValue1);
                                        if (newProperties == null)
                                        {
                                            continue;
                                        }
                                        newProperties.Add(edmPropertyValue1);
                                    }
                                    else
                                    {
                                        flag = false;
                                        return(flag);
                                    }
                                }
                                else
                                {
                                    flag = false;
                                    return(flag);
                                }
                            }
                        }
                    }
                    if (newProperties != null)
                    {
                        IEnumerator <IEdmPropertyValue> enumerator2 = structuredValue.PropertyValues.GetEnumerator();
                        using (enumerator2)
                        {
                            while (enumerator2.MoveNext())
                            {
                                IEdmPropertyValue current1 = enumerator2.Current;
                                if (edmPropertyValues.Contains(current1))
                                {
                                    continue;
                                }
                                newProperties.Add(current1);
                            }
                        }
                    }
                    return(true);
                }
                return(flag);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 31
0
        internal List <ODataProperty> AppendDynamicProperties(object source, IEdmStructuredTypeReference structuredType,
                                                              ODataSerializerContext writeContext, List <ODataProperty> declaredProperties,
                                                              string[] selectedDynamicProperties)
        {
            Contract.Assert(source != null);
            Contract.Assert(structuredType != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(writeContext.Model != null);

            bool nullDynamicPropertyEnabled = false;

            if (source is EdmDeltaComplexObject || source is EdmDeltaEntityObject)
            {
                nullDynamicPropertyEnabled = true;
            }
            else if (writeContext.Request != null)
            {
                HttpConfiguration configuration = writeContext.Request.GetConfiguration();
                if (configuration != null)
                {
                    nullDynamicPropertyEnabled = configuration.HasEnabledNullDynamicProperty();
                }
            }

            PropertyInfo dynamicPropertyInfo = EdmLibHelpers.GetDynamicPropertyDictionary(
                structuredType.StructuredDefinition(), writeContext.Model);

            IEdmStructuredObject structuredObject = source as IEdmStructuredObject;
            object value;
            IDelta delta = source as IDelta;

            if (delta == null)
            {
                if (dynamicPropertyInfo == null || structuredObject == null ||
                    !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null)
                {
                    return(null);
                }
            }
            else
            {
                value = ((EdmStructuredObject)structuredObject).TryGetDynamicProperties();
            }

            IDictionary <string, object> dynamicPropertyDictionary = (IDictionary <string, object>)value;

            // Build a HashSet to store the declared property names.
            // It is used to make sure the dynamic property name is different from all declared property names.
            HashSet <string>     declaredPropertyNameSet = new HashSet <string>(declaredProperties.Select(p => p.Name));
            List <ODataProperty> dynamicProperties       = new List <ODataProperty>();
            IEnumerable <KeyValuePair <string, object> > dynamicPropertiesToSelect =
                dynamicPropertyDictionary.Where(
                    x => !selectedDynamicProperties.Any() || selectedDynamicProperties.Contains(x.Key));

            foreach (KeyValuePair <string, object> dynamicProperty in dynamicPropertiesToSelect)
            {
                if (String.IsNullOrEmpty(dynamicProperty.Key))
                {
                    continue;
                }

                if (dynamicProperty.Value == null)
                {
                    if (nullDynamicPropertyEnabled)
                    {
                        dynamicProperties.Add(new ODataProperty
                        {
                            Name  = dynamicProperty.Key,
                            Value = new ODataNullValue()
                        });
                    }

                    continue;
                }

                if (declaredPropertyNameSet.Contains(dynamicProperty.Key))
                {
                    throw Error.InvalidOperation(SRResources.DynamicPropertyNameAlreadyUsedAsDeclaredPropertyName,
                                                 dynamicProperty.Key, structuredType.FullName());
                }

                IEdmTypeReference edmTypeReference = writeContext.GetEdmType(dynamicProperty.Value,
                                                                             dynamicProperty.Value.GetType());
                if (edmTypeReference == null)
                {
                    throw Error.NotSupported(SRResources.TypeOfDynamicPropertyNotSupported,
                                             dynamicProperty.Value.GetType().FullName, dynamicProperty.Key);
                }

                ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference);
                if (propertySerializer == null)
                {
                    throw Error.NotSupported(SRResources.DynamicPropertyCannotBeSerialized, dynamicProperty.Key,
                                             edmTypeReference.FullName());
                }

                dynamicProperties.Add(propertySerializer.CreateProperty(
                                          dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, writeContext));
            }

            return(dynamicProperties);
        }
        /// <summary>
        /// Walk the JSON body and change outgoing V4 properties that would serialize in an unexpected way to properties that will
        /// serialize in a way understood by V3 OData clients.
        /// </summary>
        /// <param name="node">JToken root or child in body</param>
        /// <param name="edmType">Corresponding type of this node</param>
        private static void WalkTranslateResponse(this JToken node, IEdmTypeReference edmType)
        {
            if (node == null)
            {
                return;
            }

            if (edmType.IsCollection() && node.Type == JTokenType.Object && node["value"] != null)
            {
                // Special case where entity type is a collection
                WalkTranslateResponse(node["value"], edmType);
            }
            else
            {
                if (node.Type == JTokenType.Object)
                {
                    JObject obj = (JObject)node;
                    IEdmStructuredTypeReference structuredType = edmType.AsStructured();
                    foreach (JProperty child in node.Children <JProperty>().ToList())
                    {
                        IEdmProperty property = structuredType.FindProperty(child.Name);

                        if (property != null &&
                            property.Type.TypeKind() == EdmTypeKind.Primitive &&
                            ((IEdmPrimitiveType)property.Type.Definition).PrimitiveKind == EdmPrimitiveTypeKind.Int64)
                        {
                            // Quote long types
                            obj[child.Name] = obj[child.Name].ToString();
                        }
                        else if (property != null)
                        {
                            // If type is not IEdmStructuredTypeReference or IEdmCollectionTypeReference, then won't need to convert.
                            if (property.Type.TypeKind() == EdmTypeKind.Collection)
                            {
                                // Translate collections
                                WalkTranslateResponse(child.Value, property.Type as IEdmCollectionTypeReference);
                            }
                            else if (property.Type.TypeKind() == EdmTypeKind.Entity ||
                                     property.Type.TypeKind() == EdmTypeKind.Complex)
                            {
                                // Continue to translate deeper entities
                                WalkTranslateResponse(child.Value, property.Type as IEdmStructuredTypeReference);
                            }
                        }
                    }
                }
                else if (node.Type == JTokenType.Array)
                {
                    JArray items = (JArray)node;
                    IEdmCollectionTypeReference collectionType = (IEdmCollectionTypeReference)edmType;
                    IEdmTypeReference           elementType    = collectionType.Definition.AsElementType().ToEdmTypeReference();

                    if (elementType != null)
                    {
                        for (int i = 0; i < items.Count; i++)
                        {
                            if (elementType.IsComplex() || elementType.IsEntity() || elementType.IsCollection())
                            {
                                // Continue to translate deeper entities
                                items[i].WalkTranslateResponse(elementType);
                            }
                            else
                            {
                                // Do translation of V3 formatted types to V4 formatted types at this primitive level
                                if (items[i].Type == JTokenType.String && elementType.IsInt64())
                                {
                                    items[i] = new JValue(items[i].ToString());
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 33
0
        /// <summary>
        /// Deserializes the nested property from <paramref name="resourceInfoWrapper"/> into <paramref name="resource"/>.
        /// </summary>
        /// <param name="resource">The object into which the nested property should be read.</param>
        /// <param name="resourceInfoWrapper">The nested resource info.</param>
        /// <param name="structuredType">The type of the resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfoWrapper resourceInfoWrapper,
                                                IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (resource == null)
            {
                throw Error.ArgumentNull(nameof(resource));
            }

            if (resourceInfoWrapper == null)
            {
                throw Error.ArgumentNull(nameof(resourceInfoWrapper));
            }

            IEdmProperty edmProperty = structuredType.FindProperty(resourceInfoWrapper.NestedResourceInfo.Name);

            if (edmProperty == null)
            {
                if (!structuredType.IsOpen())
                {
                    throw new ODataException(
                              Error.Format(SRResources.NestedPropertyNotfound, resourceInfoWrapper.NestedResourceInfo.Name,
                                           structuredType.FullName()));
                }
            }

            IList <ODataItemWrapper> nestedItems;
            var referenceLinks = resourceInfoWrapper.NestedItems.OfType <ODataEntityReferenceLinkWrapper>().ToArray();

            if (referenceLinks.Length > 0)
            {
                // Be noted:
                // 1) OData v4.0, it's "*****@*****.**", and we get "ODataEntityReferenceLinkWrapper"(s) for that.
                // 2) OData v4.01, it's {"odata.id" ...}, and we get "ODataResource"(s) for that.
                // So, in OData v4, if it's a single, NestedItems contains one ODataEntityReferenceLinkWrapper,
                // if it's a collection, NestedItems contains multiple ODataEntityReferenceLinkWrapper(s)
                // We can use the following codes to adjust the `ODataEntityReferenceLinkWrapper` to `ODataResourceWrapper`.
                // In OData v4.01, we will not be here.
                // Only supports declared property
                Contract.Assert(edmProperty != null);

                nestedItems = new List <ODataItemWrapper>();
                if (edmProperty.Type.IsCollection())
                {
                    IEdmCollectionTypeReference edmCollectionTypeReference = edmProperty.Type.AsCollection();
                    ODataResourceSetWrapper     resourceSetWrapper         = CreateResourceSetWrapper(edmCollectionTypeReference, referenceLinks, readContext);
                    nestedItems.Add(resourceSetWrapper);
                }
                else
                {
                    ODataResourceWrapper resourceWrapper = CreateResourceWrapper(edmProperty.Type, referenceLinks[0], readContext);
                    nestedItems.Add(resourceWrapper);
                }
            }
            else
            {
                nestedItems = resourceInfoWrapper.NestedItems;
            }

            foreach (ODataItemWrapper childItem in nestedItems)
            {
                // it maybe null.
                if (childItem == null)
                {
                    if (edmProperty == null)
                    {
                        // for the dynamic, OData.net has a bug. see https://github.com/OData/odata.net/issues/977
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, null, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, null, readContext);
                    }
                }

                ODataResourceSetWrapper resourceSetWrapper = childItem as ODataResourceSetWrapper;
                if (resourceSetWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceSetInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name,
                                                                resource, structuredType, resourceSetWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceSetInNestedProperty(edmProperty, resource, resourceSetWrapper, readContext);
                    }

                    continue;
                }

                if (childItem is ODataDeltaResourceSetWrapper deltaResourceSetWrapper)
                {
                    Contract.Assert(edmProperty != null, "nested delta resource cannot be dynamic property!");
                    ApplyNestedDeltaResourceSet(edmProperty, resource, deltaResourceSetWrapper, readContext);
                    continue;
                }

                // It must be resource by now.
                ODataResourceWrapper resourceWrapper = (ODataResourceWrapper)childItem;
                if (resourceWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, resourceWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, resourceWrapper, readContext);
                    }
                }
            }
        }
        private async Task WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer,
                                            ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(resourceSetType != null);

            IEdmStructuredTypeReference elementType = GetResourceType(resourceSetType);
            ODataResourceSet            resourceSet = CreateResourceSet(enumerable, resourceSetType.AsCollection(), writeContext);

            if (resourceSet == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                resourceSet.SetSerializationInfo(new ODataResourceSerializationInfo
                {
                    IsFromCollection = true,
                    NavigationSourceEntityTypeName = elementType.FullName(),
                    NavigationSourceKind           = EdmNavigationSourceKind.UnknownEntitySet,
                    NavigationSourceName           = null
                });
            }

            ODataEdmTypeSerializer resourceSerializer = SerializerProvider.GetEdmTypeSerializer(writeContext.Context, elementType);

            if (resourceSerializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataOutputFormatter).Name));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = resourceSet.NextPageLink;

            resourceSet.CountOnly    = enumerable is ICountOptionCollection && (enumerable as ITruncatedCollection).OnlyCount;
            resourceSet.NextPageLink = null;

            writer.WriteStart(resourceSet);

            foreach (object item in enumerable)
            {
                if (item == null || item is NullEdmComplexObject)
                {
                    if (elementType.IsEntity())
                    {
                        throw new SerializationException(SRResources.NullElementInCollection);
                    }

                    // for null complex element, it can be serialized as "null" in the collection.
                    writer.WriteStart(resource: null);
                    writer.WriteEnd();
                }
                else
                {
                    await resourceSerializer.WriteObjectInlineAsync(item, elementType, writer, writeContext);
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(resourceSet),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(resourceSet) but is instead set later on that resourceSet
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.

            if (nextPageLink != null)
            {
                resourceSet.NextPageLink = nextPageLink;
            }

            writer.WriteEnd();
        }
Exemplo n.º 35
0
        private void SetEpmValueForSegment(
            EntityPropertyMappingInfo epmInfo,
            int propertyValuePathIndex,
            IEdmStructuredTypeReference segmentStructuralTypeReference,
            List<ODataProperty> existingProperties,
            object propertyValue)
        {
            Debug.Assert(epmInfo != null, "epmInfo != null");
            Debug.Assert(propertyValuePathIndex < epmInfo.PropertyValuePath.Length, "The propertyValuePathIndex is out of bounds.");
            Debug.Assert(existingProperties != null, "existingProperties != null");

            string propertyName = epmInfo.PropertyValuePath[propertyValuePathIndex].PropertyName;

            // Do not set out-of-content values if the EPM is defined as KeepInContent=true.
            if (epmInfo.Attribute.KeepInContent)
            {
                return;
            }

            // Try to find the property in the existing properties
            // If the property value is atomic from point of view of EPM (non-streaming collection or primitive) then if it already exists
            // it must have been in-content, and thus we leave it as is (note that two EPMs can't map to the same property, we verify that upfront).
            // If the property value is non-atomic, then it is a complex value, we might want to merge the new value comming from EPM with it.
            ODataProperty existingProperty = existingProperties.FirstOrDefault(p => string.CompareOrdinal(p.Name, propertyName) == 0);
            ODataComplexValue existingComplexValue = null;
            if (existingProperty != null)
            {
                // In case the property exists and it's a complex value we will try to merge.
                // Note that if the property is supposed to be complex, but it already has a null value, then the null wins.
                // Since in-content null complex value wins over any EPM complex value.
                existingComplexValue = existingProperty.Value as ODataComplexValue;
                if (existingComplexValue == null)
                {
                    return;
                }
            }

            IEdmProperty propertyMetadata = segmentStructuralTypeReference.FindProperty(propertyName);
            Debug.Assert(propertyMetadata != null || segmentStructuralTypeReference.IsOpen(), "We should have verified that if the property is not declared the type must be open.");

            if (propertyMetadata == null && propertyValuePathIndex != epmInfo.PropertyValuePath.Length - 1)
            {
                throw new ODataException(o.Strings.EpmReader_OpenComplexOrCollectionEpmProperty(epmInfo.Attribute.SourcePath));
            }

            // Open properties in EPM are by default of type Edm.String - there's no way to specify a typename in EPM
            // consumer is free to do the conversion later on if it needs to.
            // Note that this effectively means that ODataMessageReaderSettings.DisablePrimitiveTypeConversion is as if it's turned on for open EPM properties.
            IEdmTypeReference propertyType;
            if (propertyMetadata == null ||
                (this.MessageReaderSettings.DisablePrimitiveTypeConversion && propertyMetadata.Type.IsODataPrimitiveTypeKind()))
            {
                propertyType = EdmCoreModel.Instance.GetString(/*nullable*/true);
            }
            else
            {
                propertyType = propertyMetadata.Type;
            }

            // NOTE: WCF DS Server only applies the values when
            // - It's an open property
            // - It's not a key property
            // - It's a key property and it's a POST operation
            // ODataLib here will always set the property though.
            switch (propertyType.TypeKind())
            {
                case EdmTypeKind.Primitive:
                    {
                        if (propertyType.IsStream())
                        {
                            throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmReader_SetEpmValueForSegment_StreamProperty));
                        }

                        object primitiveValue;
                        if (propertyValue == null)
                        {
                            ReaderValidationUtils.ValidateNullValue(this.atomInputContext.Model, propertyType, this.atomInputContext.MessageReaderSettings, /*validateNullValue*/ true, this.atomInputContext.Version);
                            primitiveValue = null;
                        }
                        else
                        {
                            // Convert the value to the desired target type
                            primitiveValue = AtomValueUtils.ConvertStringToPrimitive((string)propertyValue, propertyType.AsPrimitive());
                        }

                        this.AddEpmPropertyValue(existingProperties, propertyName, primitiveValue, segmentStructuralTypeReference.IsODataEntityTypeKind());
                    }

                    break;

                case EdmTypeKind.Complex:
                    // Note: Unlike WCF DS we don't have a preexisting instance to override (since complex values are atomic, so we should not updated them)
                    // In our case the complex value either doesn't exist yet on the entry being reported (easy, create it)
                    // or it exists, but then it was created during reading of previous normal or EPM properties for this entry. It never exists before
                    // we ever get to see the entity. So in our case we will never recreate the complex value, we always start with new one
                    // and update it with new properties as they come. (Next time we will start over with a new complex value.)
                    Debug.Assert(
                        existingComplexValue == null || (existingProperty != null && existingProperty.Value == existingComplexValue),
                        "If we have existing complex value, we must have an existing property as well.");
                    Debug.Assert(
                        epmInfo.PropertyValuePath.Length > propertyValuePathIndex + 1,
                        "Complex value can not be a leaf segment in the source property path. We should have failed constructing the EPM trees for it.");

                    if (existingComplexValue == null)
                    {
                        Debug.Assert(existingProperty == null, "If we don't have an existing complex value, then we must not have an existing property at all.");

                        // Create a new complex value and set its type name to the type name of the property type (in case of EPM we never have type name from the payload)
                        existingComplexValue = new ODataComplexValue
                        {
                            TypeName = propertyType.ODataFullName(),
                            Properties = new ReadOnlyEnumerable<ODataProperty>()
                        };

                        this.AddEpmPropertyValue(existingProperties, propertyName, existingComplexValue, segmentStructuralTypeReference.IsODataEntityTypeKind());
                    }

                    // Get the properties list of the complex value and recursively set the next EPM segment value to it.
                    // Note that on inner complex value we don't need to check for duplicate properties
                    // because EPM will never add a property which already exists (see the start of this method).
                    IEdmComplexTypeReference complexPropertyTypeReference = propertyType.AsComplex();
                    Debug.Assert(complexPropertyTypeReference != null, "complexPropertyTypeReference != null");
                    this.SetEpmValueForSegment(
                        epmInfo,
                        propertyValuePathIndex + 1,
                        complexPropertyTypeReference,
                        ReaderUtils.GetPropertiesList(existingComplexValue.Properties),
                        propertyValue);

                    break;

                case EdmTypeKind.Collection:
                    Debug.Assert(propertyType.IsNonEntityODataCollectionTypeKind(), "Collection types in EPM must be atomic.");

                    // In this case the property value is the internal list of items.
                    // Create a new collection value and set the list as the list of items on it.
                    ODataCollectionValue collectionValue = new ODataCollectionValue
                    {
                        TypeName = propertyType.ODataFullName(),
                        Items = new ReadOnlyEnumerable((List<object>)propertyValue)
                    };

                    this.AddEpmPropertyValue(existingProperties, propertyName, collectionValue, segmentStructuralTypeReference.IsODataEntityTypeKind());

                    break;
                default:
                    throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmReader_SetEpmValueForSegment_TypeKind));
            }
        }
Exemplo n.º 36
0
        /// <summary>
        /// Creates a new instance of the backing CLR object for the given resource type.
        /// </summary>
        /// <param name="structuredType">The EDM type of the resource to create.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The created CLR object.</returns>
        public virtual object CreateResourceInstance(IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (structuredType == null)
            {
                throw new ArgumentNullException(nameof(structuredType));
            }

            if (readContext == null)
            {
                throw new ArgumentNullException(nameof(readContext));
            }

            IEdmModel model = readContext.Model;

            if (model == null)
            {
                throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
            }

            if (readContext.IsUntyped)
            {
                if (structuredType.IsEntity())
                {
                    return(new EdmEntityObject(structuredType.AsEntity()));
                }

                return(new EdmComplexObject(structuredType.AsComplex()));
            }
            else
            {
                Type clrType = model.GetClrType(structuredType);
                if (clrType == null)
                {
                    throw new ODataException(
                              Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName()));
                }

                if (readContext.IsDeltaOfT)
                {
                    IEnumerable <string> structuralProperties = structuredType.StructuralProperties()
                                                                .Select(edmProperty => model.GetClrPropertyName(edmProperty));

                    if (structuredType.IsOpen())
                    {
                        PropertyInfo dynamicDictionaryPropertyInfo = model.GetDynamicPropertyDictionary(
                            structuredType.StructuredDefinition());

                        return(Activator.CreateInstance(readContext.ResourceType, clrType, structuralProperties,
                                                        dynamicDictionaryPropertyInfo));
                    }
                    else
                    {
                        return(Activator.CreateInstance(readContext.ResourceType, clrType, structuralProperties));
                    }
                }
                else
                {
                    return(Activator.CreateInstance(clrType));
                }
            }
        }
Exemplo n.º 37
0
 private object ReadPropertyValue(EntityPropertyMappingInfo epmInfo, IEnumerable<ODataProperty> cachedProperties, int sourceSegmentIndex, IEdmStructuredTypeReference structuredTypeReference, EpmValueCache epmValueCache)
 {
     EpmSourcePathSegment segment = epmInfo.PropertyValuePath[sourceSegmentIndex];
     string propertyName = segment.PropertyName;
     bool flag = epmInfo.PropertyValuePath.Length == (sourceSegmentIndex + 1);
     IEdmStructuredType owningStructuredType = structuredTypeReference.StructuredDefinition();
     IEdmProperty expectedProperty = WriterValidationUtils.ValidatePropertyDefined(propertyName, owningStructuredType);
     if (expectedProperty != null)
     {
         if (flag)
         {
             if (!expectedProperty.Type.IsODataPrimitiveTypeKind() && !expectedProperty.Type.IsNonEntityODataCollectionTypeKind())
             {
                 throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_EndsWithNonPrimitiveType(propertyName));
             }
         }
         else if (expectedProperty.Type.TypeKind() != EdmTypeKind.Complex)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_TraversalOfNonComplexType(propertyName));
         }
     }
     ODataProperty property2 = (cachedProperties == null) ? null : cachedProperties.FirstOrDefault<ODataProperty>(p => (p.Name == propertyName));
     if (property2 == null)
     {
         throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_MissingPropertyOnInstance(propertyName, structuredTypeReference.ODataFullName()));
     }
     object obj2 = property2.Value;
     ODataComplexValue complexValue = obj2 as ODataComplexValue;
     if (flag)
     {
         if (obj2 == null)
         {
             WriterValidationUtils.ValidateNullPropertyValue(expectedProperty, this.WriterBehavior, this.atomOutputContext.Model);
             return obj2;
         }
         if (complexValue != null)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_EndsWithNonPrimitiveType(propertyName));
         }
         ODataCollectionValue value3 = obj2 as ODataCollectionValue;
         if (value3 != null)
         {
             string str = value3.TypeName;
             WriterValidationUtils.ResolveTypeNameForWriting(this.atomOutputContext.Model, (expectedProperty == null) ? null : expectedProperty.Type, ref str, EdmTypeKind.Collection, expectedProperty == null);
             return obj2;
         }
         if (obj2 is ODataStreamReferenceValue)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ODataWriter_StreamPropertiesMustBePropertiesOfODataEntry(propertyName));
         }
         if (obj2 is ISpatial)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_OpenPropertySpatialTypeCannotBeMapped(propertyName, epmInfo.DefiningType.FullName()));
         }
         if (expectedProperty != null)
         {
             ValidationUtils.ValidateIsExpectedPrimitiveType(obj2, expectedProperty.Type);
         }
         return obj2;
     }
     if (complexValue == null)
     {
         if (obj2 != null)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_TraversalOfNonComplexType(propertyName));
         }
         return null;
     }
     string typeName = complexValue.TypeName;
     IEdmComplexTypeReference complexType = WriterValidationUtils.ResolveTypeNameForWriting(this.atomOutputContext.Model, (expectedProperty == null) ? null : expectedProperty.Type, ref typeName, EdmTypeKind.Complex, expectedProperty == null).AsComplexOrNull();
     return this.ReadComplexPropertyValue(epmInfo, complexValue, epmValueCache, sourceSegmentIndex + 1, complexType);
 }
Exemplo n.º 38
0
 private void ApplyResourceProperties(object resource, ODataResourceWrapper resourceWrapper,
                                      IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
 {
     ApplyStructuralProperties(resource, resourceWrapper, structuredType, readContext);
     ApplyNestedProperties(resource, resourceWrapper, structuredType, readContext);
 }
Exemplo n.º 39
0
        private void SetPropertyValue(ODataSerializerContext writeContext, List <ODataProperty> properties, IEdmStructuredTypeReference expectedType, string propertyName, object propertyValue)
        {
            if (propertyValue == null && expectedType == null)
            {
                properties.Add(new ODataProperty {
                    Name = propertyName, Value = new ODataNullValue()
                });
            }
            else
            {
                IEdmTypeReference      edmTypeReference;
                ODataEdmTypeSerializer edmTypeSerializer = null;

                edmTypeReference = propertyValue == null ? expectedType : writeContext.GetEdmType(propertyValue,
                                                                                                  propertyValue.GetType());

                if (edmTypeReference != null)
                {
                    edmTypeSerializer = GetResourceValueEdmTypeSerializer(edmTypeReference);
                }

                if (edmTypeSerializer != null)
                {
                    ODataValue odataValue = edmTypeSerializer.CreateODataValue(propertyValue, edmTypeReference, writeContext);
                    properties.Add(new ODataProperty {
                        Name = propertyName, Value = odataValue
                    });
                }
            }
        }
Exemplo n.º 40
0
        private void ApplyDynamicResourceSetInNestedProperty(string propertyName, object resource, IEdmStructuredTypeReference structuredType,
                                                             ODataResourceSetWrapper resourceSetWrapper, ODataDeserializerContext readContext)
        {
            Contract.Assert(resource != null);
            Contract.Assert(readContext != null);

            if (string.IsNullOrEmpty(resourceSetWrapper.ResourceSet.TypeName))
            {
                string message = Error.Format(SRResources.DynamicResourceSetTypeNameIsRequired, propertyName);
                throw new ODataException(message);
            }

            string elementTypeName =
                DeserializationHelpers.GetCollectionElementTypeName(resourceSetWrapper.ResourceSet.TypeName,
                                                                    isNested: false);
            IEdmSchemaType elementType = readContext.Model.FindDeclaredType(elementTypeName);

            IEdmTypeReference          edmTypeReference = elementType.ToEdmTypeReference(true);
            EdmCollectionTypeReference collectionType   = new EdmCollectionTypeReference(new EdmCollectionType(edmTypeReference));

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(collectionType);

            if (deserializer == null)
            {
                throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, collectionType.FullName()));
            }

            IEnumerable value  = ReadNestedResourceSetInline(resourceSetWrapper, collectionType, readContext) as IEnumerable;
            object      result = value;

            if (value != null)
            {
                if (readContext.IsUntyped)
                {
                    result = value.ConvertToEdmObject(collectionType);
                }
            }

            DeserializationHelpers.SetDynamicProperty(resource, structuredType, EdmTypeKind.Collection, propertyName,
                                                      result, collectionType, readContext.Model);
        }
Exemplo n.º 41
0
        internal List <ODataProperty> AppendDynamicProperties(object source, IEdmStructuredTypeReference structuredType,
                                                              ODataSerializerContext writeContext, List <ODataProperty> declaredProperties)
        {
            Contract.Assert(source != null);
            Contract.Assert(structuredType != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(writeContext.Model != null);

            PropertyInfo dynamicPropertyInfo = EdmLibHelpers.GetDynamicPropertyDictionary(
                structuredType.StructuredDefinition(), writeContext.Model);

            IEdmStructuredObject structuredObject = source as IEdmStructuredObject;
            object value;

            if (dynamicPropertyInfo == null || structuredObject == null ||
                !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null)
            {
                return(null);
            }

            IDictionary <string, object> dynamicPropertyDictionary = (IDictionary <string, object>)value;

            // Build a HashSet to store the declared property names.
            // It is used to make sure the dynamic property name is different from all declared property names.
            HashSet <string>     declaredPropertyNameSet = new HashSet <string>(declaredProperties.Select(p => p.Name));
            List <ODataProperty> dynamicProperties       = new List <ODataProperty>();

            foreach (KeyValuePair <string, object> dynamicProperty in dynamicPropertyDictionary)
            {
                if (String.IsNullOrEmpty(dynamicProperty.Key) || dynamicProperty.Value == null)
                {
                    continue; // skip the null object
                }

                if (declaredPropertyNameSet.Contains(dynamicProperty.Key))
                {
                    throw Error.InvalidOperation(SRResources.DynamicPropertyNameAlreadyUsedAsDeclaredPropertyName,
                                                 dynamicProperty.Key, structuredType.FullName());
                }

                IEdmTypeReference edmTypeReference = writeContext.GetEdmType(dynamicProperty.Value,
                                                                             dynamicProperty.Value.GetType());
                if (edmTypeReference == null)
                {
                    throw Error.NotSupported(SRResources.TypeOfDynamicPropertyNotSupported,
                                             dynamicProperty.Value.GetType().FullName, dynamicProperty.Key);
                }

                ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference);
                if (propertySerializer == null)
                {
                    throw Error.NotSupported(SRResources.DynamicPropertyCannotBeSerialized, dynamicProperty.Key,
                                             edmTypeReference.FullName());
                }

                dynamicProperties.Add(propertySerializer.CreateProperty(
                                          dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, writeContext));
            }

            return(dynamicProperties);
        }
Exemplo n.º 42
0
        /// <summary>
        /// Create the <see cref="ODataResourceSet"/> to be written for the given resourceSet instance.
        /// </summary>
        /// <param name="resourceSetInstance">The instance representing the resourceSet being written.</param>
        /// <param name="resourceSetType">The EDM type of the resourceSet being written.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataResourceSet"/> object.</returns>
        public virtual ODataResourceSet CreateResourceSet(IEnumerable resourceSetInstance, IEdmCollectionTypeReference resourceSetType,
                                                          ODataSerializerContext writeContext)
        {
            ODataResourceSet resourceSet = new ODataResourceSet
            {
                TypeName = resourceSetType.FullName()
            };

            IEdmStructuredTypeReference structuredType = GetResourceType(resourceSetType).AsStructured();

            if (writeContext.NavigationSource != null && structuredType.IsEntity())
            {
                ResourceSetContext resourceSetContext = ResourceSetContext.Create(writeContext, resourceSetInstance);
                IEdmEntityType     entityType         = structuredType.AsEntity().EntityDefinition();
                var operations      = writeContext.Model.GetAvailableOperationsBoundToCollection(entityType);
                var odataOperations = CreateODataOperations(operations, resourceSetContext, writeContext);
                foreach (var odataOperation in odataOperations)
                {
                    ODataAction action = odataOperation as ODataAction;
                    if (action != null)
                    {
                        resourceSet.AddAction(action);
                    }
                    else
                    {
                        resourceSet.AddFunction((ODataFunction)odataOperation);
                    }
                }
            }

            if (writeContext.ExpandedResource == null)
            {
                // If we have more OData format specific information apply it now, only if we are the root feed.
                PageResult odataResourceSetAnnotations = resourceSetInstance as PageResult;
                if (odataResourceSetAnnotations != null)
                {
                    resourceSet.Count        = odataResourceSetAnnotations.Count;
                    resourceSet.NextPageLink = odataResourceSetAnnotations.NextPageLink;
                }
                else if (writeContext.Request != null)
                {
                    resourceSet.NextPageLink = writeContext.InternalRequest.Context.NextLink;
                    resourceSet.DeltaLink    = writeContext.InternalRequest.Context.DeltaLink;

                    long?countValue = writeContext.InternalRequest.Context.TotalCount;
                    if (countValue.HasValue)
                    {
                        resourceSet.Count = countValue.Value;
                    }
                }
            }
            else
            {
                ICountOptionCollection countOptionCollection = resourceSetInstance as ICountOptionCollection;
                if (countOptionCollection != null && countOptionCollection.TotalCount != null)
                {
                    resourceSet.Count = countOptionCollection.TotalCount;
                }
            }

            return(resourceSet);
        }
Exemplo n.º 43
0
        /// <summary>
        /// Reads a property value starting with the specified index to the property value path.
        /// </summary>
        /// <param name="epmInfo">The EPM info which describes the mapping for which to read the property value.</param>
        /// <param name="cachedProperties">The enumeration of properties to search for the first property in the property value path.</param>
        /// <param name="sourceSegmentIndex">The index in the property value path to start with.</param>
        /// <param name="structuredTypeReference">The type of the entry or complex value the <paramref name="cachedProperties"/> enumeration belongs to.</param>
        /// <param name="epmValueCache">The EPM value cache to use.</param>
        /// <returns>The value of the property (may be null), or null if the property itself was not found due to one of its parent properties being null.</returns>
        private object ReadPropertyValue(
            EntityPropertyMappingInfo epmInfo,
            IEnumerable<ODataProperty> cachedProperties,
            int sourceSegmentIndex,
            IEdmStructuredTypeReference structuredTypeReference,
            EpmValueCache epmValueCache)
        {
            Debug.Assert(epmInfo != null, "epmInfo != null");
            Debug.Assert(epmInfo.PropertyValuePath != null, "The PropertyValuePath should have been initialized by now.");
            Debug.Assert(epmInfo.PropertyValuePath.Length > sourceSegmentIndex, "The PropertyValuePath must be at least as long as the source segment index.");
            Debug.Assert(structuredTypeReference != null, "structuredTypeReference != null");
            Debug.Assert(epmValueCache != null, "epmValueCache != null");

            EpmSourcePathSegment sourceSegment = epmInfo.PropertyValuePath[sourceSegmentIndex];
            string propertyName = sourceSegment.PropertyName;
            bool lastSegment = epmInfo.PropertyValuePath.Length == sourceSegmentIndex + 1;

            IEdmStructuredType structuredType = structuredTypeReference.StructuredDefinition();
            IEdmProperty edmProperty = WriterValidationUtils.ValidatePropertyDefined(propertyName, structuredType);
            if (edmProperty != null)
            {
                // If this is the last part of the path, then it has to be a primitive or atomic collection type otherwise should be a complex type
                if (lastSegment)
                {
                    if (!edmProperty.Type.IsODataPrimitiveTypeKind() && !edmProperty.Type.IsNonEntityODataCollectionTypeKind())
                    {
                        throw new ODataException(o.Strings.EpmSourceTree_EndsWithNonPrimitiveType(propertyName));
                    }
                }
                else
                {
                    if (edmProperty.Type.TypeKind() != EdmTypeKind.Complex)
                    {
                        throw new ODataException(o.Strings.EpmSourceTree_TraversalOfNonComplexType(propertyName));
                    }
                }
            }
            else
            {
                Debug.Assert(
                    structuredType.IsOpen,
                    "Only open types can have undeclared properties, otherwise we should have failed in the ValidatePropertyDefined method.");
            }

            ODataProperty property = cachedProperties == null ? null : cachedProperties.FirstOrDefault(p => p.Name == propertyName);
            if (property == null)
            {
                throw new ODataException(o.Strings.EpmSourceTree_MissingPropertyOnInstance(propertyName, structuredTypeReference.ODataFullName()));
            }

            object propertyValue = property.Value;
            ODataComplexValue propertyComplexValue = propertyValue as ODataComplexValue;
            if (lastSegment)
            {
                if (propertyValue == null)
                {
                    WriterValidationUtils.ValidateNullPropertyValue(edmProperty, this.WriterBehavior, this.atomOutputContext.Model);
                }
                else
                {
                    // If this property is the last one it has to be either a primitive or collection
                    if (propertyComplexValue != null)
                    {
                        throw new ODataException(o.Strings.EpmSourceTree_EndsWithNonPrimitiveType(propertyName));
                    }
                    else
                    {
                        ODataCollectionValue propertyCollectionValue = propertyValue as ODataCollectionValue;
                        if (propertyCollectionValue != null)
                        {
                            // Validate the type name for the collection
                            string typeName = propertyCollectionValue.TypeName;
                            WriterValidationUtils.ResolveTypeNameForWriting(
                                this.atomOutputContext.Model,
                                edmProperty == null ? null : edmProperty.Type,
                                ref typeName,
                                EdmTypeKind.Collection,
                                edmProperty == null);
                        }
                        else
                        {
                            if (propertyValue is ODataStreamReferenceValue)
                            {
                                // Stream properties should not come here, if it were an ODataEntry property it would have been 
                                // filtered in ReadEntryPropertyValue() by "epmValueCache.EntryProperties" call.
                                throw new ODataException(o.Strings.ODataWriter_StreamPropertiesMustBePropertiesOfODataEntry(propertyName));
                            }
                            else if (propertyValue is ISpatial)
                            {
                                throw new ODataException(o.Strings.EpmSourceTree_OpenPropertySpatialTypeCannotBeMapped(propertyName, epmInfo.DefiningType.FullName()));
                            }
                            else if (edmProperty != null)
                            {
                                ValidationUtils.ValidateIsExpectedPrimitiveType(propertyValue, edmProperty.Type);
                            }
                        }
                    }
                }

                return propertyValue;
            }

            // Otherwise it's in the middle and thus it must be a complex value
            if (propertyComplexValue == null)
            {
                if (propertyValue != null)
                {
                    // It's not a complex value - fail.
                    throw new ODataException(o.Strings.EpmSourceTree_TraversalOfNonComplexType(propertyName));
                }
                else
                {
                    // The value of the property is null, which can be a null complex value
                    // Note that we must not attempt to resolve the type as if the type name was null here, because
                    //  1) We don't need the type for anything anyway (the value is null, this is the end)
                    //  2) If the property is open, trying to resolve a null type name would throw
                    //     but we don't have a null type name, we have a null entire value.
                    return null;
                }
            }

            string localTypeName = propertyComplexValue.TypeName;
            IEdmComplexTypeReference complexValueType = WriterValidationUtils.ResolveTypeNameForWriting(
                this.atomOutputContext.Model,
                edmProperty == null ? null : edmProperty.Type,
                ref localTypeName,
                EdmTypeKind.Complex,
                edmProperty == null).AsComplexOrNull();

            return this.ReadComplexPropertyValue(
                epmInfo,
                propertyComplexValue,
                epmValueCache,
                sourceSegmentIndex + 1,
                complexValueType);
        }
Exemplo n.º 44
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmStructuredTypeReference"/> of this object.</param>
 protected EdmStructuredObject(IEdmStructuredTypeReference edmType)
     : this(edmType.StructuredDefinition(), edmType.IsNullable)
 {
 }
Exemplo n.º 45
0
        /// <summary>
        /// Binds an end path token into a PropertyAccessToken, OpenPropertyToken, or FunctionCallToken.
        /// </summary>
        /// <param name="endPathToken">The property access token to bind.</param>
        /// <returns>A Query node representing this endpath token, bound to metadata.</returns>
        internal QueryNode BindEndPath(EndPathToken endPathToken)
        {
            ExceptionUtils.CheckArgumentNotNull(endPathToken, "EndPathToken");
            ExceptionUtils.CheckArgumentStringNotNullOrEmpty(endPathToken.Identifier, "EndPathToken.Identifier");

            // Set the parent (get the parent type, so you can check whether the Identifier inside EndPathToken really is legit offshoot of the parent type)
            QueryNode parent = this.DetermineParentNode(endPathToken);

            QueryNode boundFunction;

            SingleValueNode singleValueParent = parent as SingleValueNode;

            if (singleValueParent != null)
            {
                if (endPathToken.Identifier == ExpressionConstants.QueryOptionCount)
                {
                    return(new CountVirtualPropertyNode());
                }

                if (state.IsCollapsed && !IsAggregatedProperty(endPathToken))
                {
                    throw new ODataException(ODataErrorStrings.ApplyBinder_GroupByPropertyNotPropertyAccessValue(endPathToken.Identifier));
                }

                // Now that we have the parent type, can find its corresponding EDM type
                IEdmStructuredTypeReference structuredParentType =
                    singleValueParent.TypeReference == null ? null : singleValueParent.TypeReference.AsStructuredOrNull();

                IEdmProperty property =
                    structuredParentType == null ? null : this.Resolver.ResolveProperty(structuredParentType.StructuredDefinition(), endPathToken.Identifier);

                if (property != null)
                {
                    return(GeneratePropertyAccessQueryNode(singleValueParent as SingleResourceNode, property, state));
                }

                if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, singleValueParent, state, out boundFunction))
                {
                    return(boundFunction);
                }

                return(GeneratePropertyAccessQueryForOpenType(endPathToken, singleValueParent));
            }

            // Collection with any or all expression is already supported and handled separately.
            // Add support of collection with $count segment.
            CollectionNode colNode = parent as CollectionNode;

            if (colNode != null && endPathToken.Identifier.Equals(UriQueryConstants.CountSegment, System.StringComparison.Ordinal))
            {
                // create a collection count node for collection node property.
                return(new CountNode(colNode));
            }

            CollectionNavigationNode collectionParent = parent as CollectionNavigationNode;

            if (collectionParent != null)
            {
                IEdmEntityTypeReference parentType = collectionParent.EntityItemType;
                IEdmProperty            property   = this.Resolver.ResolveProperty(parentType.StructuredDefinition(), endPathToken.Identifier);

                if (property.PropertyKind == EdmPropertyKind.Structural &&
                    !property.Type.IsCollection() &&
                    this.state.InEntitySetAggregation)
                {
                    return(new AggregatedCollectionPropertyNode(collectionParent, property));
                }
            }

            if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, parent, state, out boundFunction))
            {
                return(boundFunction);
            }

            throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyAccessSourceNotSingleValue(endPathToken.Identifier));
        }
Exemplo n.º 46
0
        internal List<ODataProperty> AppendDynamicProperties(object source, IEdmStructuredTypeReference structuredType,
            ODataSerializerContext writeContext, List<ODataProperty> declaredProperties,
            string[] selectedDynamicProperties)
        {
            Contract.Assert(source != null);
            Contract.Assert(structuredType != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(writeContext.Model != null);

            PropertyInfo dynamicPropertyInfo = EdmLibHelpers.GetDynamicPropertyDictionary(
                structuredType.StructuredDefinition(), writeContext.Model);

            IEdmStructuredObject structuredObject = source as IEdmStructuredObject;
            object value;
            IDelta delta = source as IDelta;
            if (delta == null)
            { 
                if (dynamicPropertyInfo == null || structuredObject == null ||
                    !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null)
                {
                    return null;
                }
            }
            else
            {
                value = ((EdmStructuredObject)structuredObject).TryGetDynamicProperties();
            }

            IDictionary<string, object> dynamicPropertyDictionary = (IDictionary<string, object>)value;

            // Build a HashSet to store the declared property names.
            // It is used to make sure the dynamic property name is different from all declared property names.
            HashSet<string> declaredPropertyNameSet = new HashSet<string>(declaredProperties.Select(p => p.Name));
            List<ODataProperty> dynamicProperties = new List<ODataProperty>();
            IEnumerable<KeyValuePair<string, object>> dynamicPropertiesToSelect =
                dynamicPropertyDictionary.Where(
                    x => !selectedDynamicProperties.Any() || selectedDynamicProperties.Contains(x.Key));
            foreach (KeyValuePair<string, object> dynamicProperty in dynamicPropertiesToSelect)
            {
                if (String.IsNullOrEmpty(dynamicProperty.Key) || dynamicProperty.Value == null)
                {
                    continue; // skip the null object
                }

                if (declaredPropertyNameSet.Contains(dynamicProperty.Key))
                {
                    throw Error.InvalidOperation(SRResources.DynamicPropertyNameAlreadyUsedAsDeclaredPropertyName,
                        dynamicProperty.Key, structuredType.FullName());
                }

                IEdmTypeReference edmTypeReference = writeContext.GetEdmType(dynamicProperty.Value,
                    dynamicProperty.Value.GetType());
                if (edmTypeReference == null)
                {
                    throw Error.NotSupported(SRResources.TypeOfDynamicPropertyNotSupported,
                        dynamicProperty.Value.GetType().FullName, dynamicProperty.Key);
                }

                ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference);
                if (propertySerializer == null)
                {
                    throw Error.NotSupported(SRResources.DynamicPropertyCannotBeSerialized, dynamicProperty.Key,
                        edmTypeReference.FullName());
                }

                dynamicProperties.Add(propertySerializer.CreateProperty(
                    dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, writeContext));
            }

            return dynamicProperties;
        }
        /// <summary>
        /// Deserializes the given <paramref name="resourceSet"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="resourceSet">The resource set to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <param name="elementType">The element type of the resource set being read.</param>
        /// <returns>The deserialized resource set object.</returns>
        public virtual IEnumerable ReadResourceSet(ODataResourceSetWrapper resourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext)
        {
            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(elementType);

            if (deserializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, elementType.FullName(), typeof(ODataInputFormatter).Name));
            }

            foreach (ODataResourceWrapper resourceWrapper in resourceSet.Resources)
            {
                yield return(deserializer.ReadInline(resourceWrapper, elementType, readContext));
            }
        }
Exemplo n.º 48
0
 public EdmRecordExpression(IEdmStructuredTypeReference declaredType, IEnumerable <IEdmPropertyConstructor> properties)
 {
     EdmUtil.CheckArgumentNull <IEnumerable <IEdmPropertyConstructor> >(properties, "properties");
     this.declaredType = declaredType;
     this.properties   = properties;
 }
        internal static void ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmProperty edmProperty = resourceType.FindProperty(property.Name);

            string propertyName = property.Name;
            IEdmTypeReference propertyType = edmProperty != null ? edmProperty.Type : null; // open properties have null values

            bool isDelta = readContext.IsPatchMode && resourceType.IsEntity();

            if (isDelta && resourceType.AsEntity().Key().Select(key => key.Name).Contains(propertyName))
            {
                // we are patching a key property.
                if (readContext.PatchKeyMode == PatchKeyMode.Ignore)
                {
                    return;
                }
                else if (readContext.PatchKeyMode == PatchKeyMode.Throw)
                {
                    throw Error.InvalidOperation(SRResources.CannotPatchKeyProperty, propertyName, resourceType.FullName(), typeof(PatchKeyMode).Name, PatchKeyMode.Throw);
                }
            }

            EdmTypeKind propertyKind;
            object value = ConvertValue(property.Value, ref propertyType, deserializerProvider, readContext, out propertyKind);

            if (propertyKind == EdmTypeKind.Primitive)
            {
                value = ConvertPrimitiveValue(value, GetPropertyType(resource, propertyName, isDelta), propertyName, resource.GetType().FullName);
            }

            SetProperty(resource, propertyName, isDelta, value);
        }
        /// <summary>
        /// Creates an expression to access a property.
        /// </summary>
        /// <param name="source">The source expression which evaluates to the instance to access the property on.</param>
        /// <param name="sourceStructuredType">The type of the source expression.</param>
        /// <param name="property">The property to access.</param>
        /// <returns>An expression which evaluates to the property value.</returns>
        private Expression CreatePropertyAccessExpression(Expression source, IEdmStructuredTypeReference sourceStructuredType, IEdmProperty property)
        {
            Debug.Assert(source != null, "source != null");
            Debug.Assert(sourceStructuredType != null, "sourceStructuredType != null");
            Debug.Assert(property != null, "property != null");
            Debug.Assert(TypeUtils.AreTypesEquivalent(source.Type, sourceStructuredType.GetInstanceType(this.model)), "source.Type != sourceStructuredType.GetInstanceType()");
#if DEBUG
            Debug.Assert(sourceStructuredType.ContainsProperty(property), "property is not declared on sourceStructuredType");
#endif

            // TODO: Deal with null propagation???
            if (property.GetCanReflectOnInstanceTypeProperty(this.model))
            {
                return Expression.Property(source, sourceStructuredType.GetPropertyInfo(property, this.model));
            }
            else
            {
                // TODO: Support for untyped and open properties
                throw new NotImplementedException();
            }
        }
Exemplo n.º 51
0
        /// <summary>
        /// Walk the JSON body and format top level instance annotations (more complex annotations are unsupported)
        /// and change types that would be deserialized incorrectly by OData V4 formatters to types that will be deserialized correctly.
        /// </summary>
        /// <param name="node">JToken root or child of JSON request body</param>
        /// <param name="edmType">Corresponding edm type</param>
        public static void WalkTranslate(this JToken node, IEdmTypeReference edmType)
        {
            if (node == null)
            {
                return;
            }

            if (node.Type == JTokenType.Object)
            {
                JObject obj = (JObject)node;
                IEdmStructuredTypeReference structuredType = edmType.AsStructured();
                foreach (JProperty child in node.Children <JProperty>().ToList())
                {
                    IEdmProperty property = structuredType.FindProperty(child.Name);

                    // Convert instance annotations to V3 format
                    if (child.Name == "odata.type")
                    {
                        obj["@odata.type"] = "#" + obj["odata.type"];
                        obj.Remove("odata.type");
                    }
                    else if (child.Name.Contains("@odata"))
                    {
                        obj[child.Name] = "#" + obj[child.Name];
                    }
                    else if (property != null &&
                             property.Type.TypeKind() == EdmTypeKind.Primitive &&
                             ((IEdmPrimitiveType)property.Type.Definition).PrimitiveKind == EdmPrimitiveTypeKind.Int64)
                    {
                        // Convert long type to unquoted when deserializing
                        obj[child.Name] = Convert.ToInt64(obj[child.Name]);
                    }
                    else if (property != null)
                    {
                        // If type is not IEdmStructuredTypeReference or IEdmCollectionTypeReference, then won't need to convert.
                        if (property.Type.TypeKind() == EdmTypeKind.Collection)
                        {
                            // Translate collection types
                            WalkTranslate(child.Value, property.Type as IEdmCollectionTypeReference);
                        }
                        else
                        {
                            // Continue to translate deeper nested entities
                            WalkTranslate(child.Value, property.Type as IEdmStructuredTypeReference);
                        }
                    }
                }
            }
            else if (node.Type == JTokenType.Array)
            {
                JArray items = (JArray)node;
                IEdmCollectionTypeReference collectionType = (IEdmCollectionTypeReference)edmType;
                IEdmTypeReference           elementType    = collectionType.Definition.AsElementType().ToEdmTypeReference();

                if (elementType != null)
                {
                    for (int i = 0; i < items.Count; i++)
                    {
                        if (elementType.IsComplex() || elementType.IsEntity() || elementType.IsCollection())
                        {
                            // Continue to translate deeper nested entities
                            items[i].WalkTranslate(elementType);
                        }
                        else
                        {
                            // Do translation of V3 formatted types to V4 formatted types at the collection level
                            if (items[i].Type == JTokenType.String && elementType.IsInt64())
                            {
                                items[i] = new JValue(Convert.ToInt64(items[i].ToString()));
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 52
0
        private static IEdmStructuredObject AsEdmResourceObject(object resourceInstance, IEdmStructuredTypeReference structuredType, IEdmModel model)
        {
            if (structuredType == null)
            {
                throw Error.ArgumentNull("structuredType");
            }

            IEdmStructuredObject edmStructuredObject = resourceInstance as IEdmStructuredObject;

            if (edmStructuredObject != null)
            {
                return(edmStructuredObject);
            }

            if (structuredType.IsEntity())
            {
                return(new TypedEdmEntityObject(resourceInstance, structuredType.AsEntity(), model));
            }

            Contract.Assert(structuredType.IsComplex());
            return(new TypedEdmComplexObject(resourceInstance, structuredType.AsComplex(), model));
        }
        /// <summary>
        /// Deserializes the nested property from <paramref name="resourceInfoWrapper"/> into <paramref name="resource"/>.
        /// </summary>
        /// <param name="resource">The object into which the nested property should be read.</param>
        /// <param name="resourceInfoWrapper">The nested resource info.</param>
        /// <param name="structuredType">The type of the resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfoWrapper resourceInfoWrapper,
                                                IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            if (resourceInfoWrapper == null)
            {
                throw new ArgumentNullException(nameof(resourceInfoWrapper));
            }

            IEdmProperty edmProperty = structuredType.FindProperty(resourceInfoWrapper.NestedResourceInfo.Name);

            if (edmProperty == null)
            {
                if (!structuredType.IsOpen())
                {
                    throw new ODataException(
                              Error.Format(SRResources.NestedPropertyNotfound, resourceInfoWrapper.NestedResourceInfo.Name,
                                           structuredType.FullName()));
                }
            }

            if (resourceInfoWrapper.NestedResourceSet != null)
            {
                // It's nested resource set.
                // So far, delta resource set is not supported yet.
                ODataResourceSetWrapper resourceSetWrapper = resourceInfoWrapper.NestedResourceSet as ODataResourceSetWrapper;
                if (resourceSetWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceSetInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name,
                                                                resource, structuredType, resourceSetWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceSetInNestedProperty(edmProperty, resource, resourceSetWrapper, readContext);
                    }
                }
            }
            else if (resourceInfoWrapper.NestedLinks == null)
            {
                // it's a nested resource, TODO, how to get rid of this logic?
                if (resourceInfoWrapper.NestedResource == null)
                {
                    if (edmProperty == null)
                    {
                        // for the dynamic, OData.net has a bug. see https://github.com/OData/odata.net/issues/977
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource, structuredType, null, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, null, readContext);
                    }
                }
                else
                {
                    // It must be resource by now. deleted resource is not supported yet.
                    ODataResourceWrapper resourceWrapper = resourceInfoWrapper.NestedResource as ODataResourceWrapper;
                    if (resourceWrapper != null)
                    {
                        if (edmProperty == null)
                        {
                            ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                                 structuredType, resourceWrapper, readContext);
                        }
                        else
                        {
                            ApplyResourceInNestedProperty(edmProperty, resource, resourceWrapper, readContext);
                        }
                    }
                }
            }
            else
            {
                // it's a nested reference link(s), ignore entity reference links.
            }
        }
Exemplo n.º 54
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ResourceContext"/> class.
 /// </summary>
 /// <param name="serializerContext">The backing <see cref="ODataSerializerContext"/>.</param>
 /// <param name="structuredType">The EDM structured type of this instance context.</param>
 /// <param name="resourceInstance">The object representing the instance of this context.</param>
 public ResourceContext(ODataSerializerContext serializerContext, IEdmStructuredTypeReference structuredType, object resourceInstance)
     : this(serializerContext, structuredType, AsEdmResourceObject(resourceInstance, structuredType, serializerContext.Model))
 {
 }
Exemplo n.º 55
0
        private static bool AssertOrMatchStructuredType(IEdmStructuredTypeReference structuredTargetType, IEdmStructuredValue structuredValue, bool testPropertyTypes, List <IEdmPropertyValue> newProperties)
        {
            // If the value has a nominal type, the target type must be derived from the nominal type for a type match to be possible.
            IEdmTypeReference operandType = structuredValue.Type;

            if (operandType != null && !structuredTargetType.StructuredDefinition().InheritsFrom(operandType.AsStructured().StructuredDefinition()))
            {
                return(false);
            }

            HashSetInternal <IEdmPropertyValue> visitedProperties = new HashSetInternal <IEdmPropertyValue>();

            foreach (IEdmProperty property in structuredTargetType.StructuralProperties())
            {
                IEdmPropertyValue propertyValue = structuredValue.FindPropertyValue(property.Name);
                if (propertyValue == null)
                {
                    return(false);
                }

                visitedProperties.Add(propertyValue);
                if (testPropertyTypes)
                {
                    if (newProperties != null)
                    {
                        newProperties.Add(new EdmPropertyValue(propertyValue.Name, Cast(property.Type, propertyValue.Value)));
                    }
                    else if (!MatchesType(property.Type, propertyValue.Value))
                    {
                        return(false);
                    }
                }
            }

            if (structuredTargetType.IsEntity())
            {
                foreach (IEdmNavigationProperty property in structuredTargetType.AsEntity().NavigationProperties())
                {
                    IEdmPropertyValue propertyValue = structuredValue.FindPropertyValue(property.Name);
                    if (propertyValue == null)
                    {
                        return(false);
                    }

                    // Make a superficial test of the navigation property value--check that it has a valid set of properties,
                    // but don't test their types.
                    if (testPropertyTypes && !MatchesType(property.Type, propertyValue.Value, false))
                    {
                        return(false);
                    }

                    visitedProperties.Add(propertyValue);
                    if (newProperties != null)
                    {
                        newProperties.Add(propertyValue);
                    }
                }
            }

            //// Allow property values not mentioned in the target type, whether or not the target type is open.

            if (newProperties != null)
            {
                foreach (IEdmPropertyValue propertyValue in structuredValue.PropertyValues)
                {
                    if (!visitedProperties.Contains(propertyValue))
                    {
                        newProperties.Add(propertyValue);
                    }
                }
            }

            return(true);
        }
 public TestEdmStructuredObject(IEdmStructuredTypeReference edmType)
     : base(edmType)
 {
 }
Exemplo n.º 57
0
		/// <summary>
		/// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
		/// </summary>
		/// <param name="edmType">The <see cref="IEdmStructuredTypeReference"/> of this object.</param>
		/// <param name="assembliesResolver">Assembly names to use for type resolution</param>
		protected EdmStructuredObject(IEdmStructuredTypeReference edmType, AssembliesResolver assembliesResolver)
            : this(edmType.StructuredDefinition(), assembliesResolver, edmType.IsNullable)
        {
        }