Beispiel #1
0
        /// <summary>
        /// Validates the specified <paramref name="property"/> matches
        /// the parsed <paramref name="link"/>.
        /// </summary>
        /// <param name="property">Property as understood by the type system.</param>
        /// <param name="link">Property as parsed.</param>
        /// <param name="model">Client Model.</param>
        /// <param name="performEntityCheck">whether to do the entity check or not.</param>
        /// <returns>The type</returns>
        internal static Type ValidatePropertyMatch(ClientPropertyAnnotation property, ODataNestedResourceInfo link, ClientEdmModel model, bool performEntityCheck)
        {
            Debug.Assert(property != null, "property != null");
            Debug.Assert(link != null, "link != null");

            Type propertyType = null;

            if (link.IsCollection.HasValue)
            {
                if (link.IsCollection.Value)
                {
                    // We need to fail if the payload states that the property is a navigation collection property or a complex collection property
                    // and in the client, the property is not a collection property.
                    if (!property.IsResourceSet)
                    {
                        throw DSClient.Error.InvalidOperation(DSClient.Strings.Deserialize_MismatchAtomLinkFeedPropertyNotCollection(property.PropertyName));
                    }

                    propertyType = property.ResourceSetItemType;
                }
                else
                {
                    if (property.IsResourceSet)
                    {
                        throw DSClient.Error.InvalidOperation(DSClient.Strings.Deserialize_MismatchAtomLinkEntryPropertyIsCollection(property.PropertyName));
                    }

                    propertyType = property.PropertyType;
                }
            }

            // If the server type and the client type does not match, we need to throw.
            // This is a breaking change from V1/V2 where we allowed materialization of entities into non-entities and vice versa
            if (propertyType != null && performEntityCheck)
            {
                if (!ClientTypeUtil.TypeIsStructured(propertyType, model))
                {
                    throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidNonEntityType(propertyType.ToString()));
                }
            }

            return(propertyType);
        }
Beispiel #2
0
        /// <summary>
        /// Gets the type that of the instances that will be returned by materializer.
        /// </summary>
        /// <param name="expectingPrimitiveValue">Whether the expected is a primitive type.</param>
        /// <param name="elementType">Actual type on the client.</param>
        /// <param name="model">The client model used.</param>
        /// <param name="implementationType">The actual type that implements ICollection&lt;&gt;</param>
        /// <returns>Type of the instances that will be returned by materializer.</returns>
        /// <remarks>
        /// For collection navigation properties (i.e. ICollection&lt;T&gt; where T is an entity the method returns T. Materializer will
        /// return single entity each time MoveNext() is called. However for collection properties we need the whole property instead of just a
        /// single collection item.
        /// </remarks>
        private static Type GetTypeForMaterializer(bool expectingPrimitiveValue, Type elementType, ClientEdmModel model, out Type implementationType)
        {
            if (!expectingPrimitiveValue && typeof(IEnumerable).IsAssignableFrom(elementType))
            {
                implementationType = ClientTypeUtil.GetImplementationType(elementType, typeof(ICollection <>));
                if (implementationType != null)
                {
                    Type expectedType = implementationType.GetGenericArguments()[0]; // already know its ICollection<>

                    // We should use the inner type only if this is a collection of entities (as opposed to a collection of primitive or complex types)
                    if (ClientTypeUtil.TypeIsStructured(expectedType, model))
                    {
                        return(expectedType);
                    }
                }
            }

            implementationType = null;
            return(elementType);
        }