Example #1
0
 internal static IEdmTypeReference ResolveAndValidateNonPrimitiveTargetType(EdmTypeKind expectedTypeKind, IEdmTypeReference expectedTypeReference, EdmTypeKind payloadTypeKind, IEdmType payloadType, string payloadTypeName, IEdmModel model, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, out SerializationTypeNameAnnotation serializationTypeNameAnnotation)
 {
     bool flag = (messageReaderSettings.ReaderBehavior.TypeResolver != null) && (payloadType != null);
     if (!flag)
     {
         ValidateTypeSupported(expectedTypeReference, version);
         if (model.IsUserModel() && ((expectedTypeReference == null) || !messageReaderSettings.DisableStrictMetadataValidation))
         {
             VerifyPayloadTypeDefined(payloadTypeName, payloadType);
         }
     }
     else
     {
         ValidateTypeSupported((payloadType == null) ? null : payloadType.ToTypeReference(true), version);
     }
     if ((payloadTypeKind != EdmTypeKind.None) && (!messageReaderSettings.DisableStrictMetadataValidation || (expectedTypeReference == null)))
     {
         ValidationUtils.ValidateTypeKind(payloadTypeKind, expectedTypeKind, payloadTypeName);
     }
     serializationTypeNameAnnotation = null;
     if (!model.IsUserModel())
     {
         return null;
     }
     if ((expectedTypeReference == null) || flag)
     {
         return ResolveAndValidateTargetTypeWithNoExpectedType(expectedTypeKind, payloadType, payloadTypeName, out serializationTypeNameAnnotation);
     }
     if (messageReaderSettings.DisableStrictMetadataValidation)
     {
         return ResolveAndValidateTargetTypeStrictValidationDisabled(expectedTypeKind, expectedTypeReference, payloadType, payloadTypeName, out serializationTypeNameAnnotation);
     }
     return ResolveAndValidateTargetTypeStrictValidationEnabled(expectedTypeKind, expectedTypeReference, payloadType, payloadTypeName, out serializationTypeNameAnnotation);
 }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (item == null)
            {
                return null;
            }

            ODataComplexValue complexValue = item as ODataComplexValue;
            if (complexValue == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataComplexValue).Name);
            }

            if (!edmType.IsComplex())
            {
                throw Error.Argument("edmType", SRResources.ArgumentMustBeOfType, EdmTypeKind.Complex);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            return ReadComplexValue(complexValue, edmType.AsComplex(), readContext);
        }
 public UnresolvedFunction(string qualifiedName, string errorMessage,  EdmLocation location)
     : base(new EdmError[] { new EdmError(location, EdmErrorCode.BadUnresolvedFunction, errorMessage) })
 {
     qualifiedName = qualifiedName ?? string.Empty;
     EdmUtil.TryGetNamespaceNameFromQualifiedName(qualifiedName, out this.namespaceName, out this.name);
     this.returnType = new BadTypeReference(new BadType(this.Errors), true);
 }
Example #4
0
		public EdmFunction(string namespaceName, string name, IEdmTypeReference returnType, string definingExpression) : base(name, returnType)
		{
			EdmUtil.CheckArgumentNull<string>(namespaceName, "namespaceName");
			EdmUtil.CheckArgumentNull<IEdmTypeReference>(returnType, "returnType");
			this.namespaceName = namespaceName;
			this.definingExpression = definingExpression;
		}
        /// <summary>
        /// Creates a new instance of the <see cref="ODataEdmTypeSerializer"/> for the given edm type.
        /// </summary>
        /// <param name="edmType">The <see cref="IEdmTypeReference"/>.</param>
        /// <returns>The constructed <see cref="ODataEdmTypeSerializer"/>.</returns>
        public virtual ODataEdmTypeSerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Primitive:
                    return new ODataPrimitiveSerializer(edmType.AsPrimitive());

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return new ODataFeedSerializer(collectionType, this);
                    }
                    else
                    {
                        return new ODataCollectionSerializer(collectionType, this);
                    }

                case EdmTypeKind.Complex:
                    return new ODataComplexTypeSerializer(edmType.AsComplex(), this);

                case EdmTypeKind.Entity:
                    return new ODataEntityTypeSerializer(edmType.AsEntity(), this);

                default:
                    return null;
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseCollectionResult" /> class.
        /// </summary>
        /// <param name="query">The query that returns a collection of objects.</param>
        /// <param name="edmType">The EDM type reference of the objects.</param>
        /// <param name="context">The context where the action is executed.</param>
        protected BaseCollectionResult(IQueryable query, IEdmTypeReference edmType, ApiContext context)
            : base(edmType, context)
        {
            Ensure.NotNull(query, "query");

            this.Query = query;
        }
Example #7
0
 public static AndConstraint<IEdmTypeReference> ShouldBeEquivalentTo(this IEdmTypeReference typeReference, IEdmTypeReference expectedTypeReference)
 {
     typeReference.IsEquivalentTo(expectedTypeReference).Should().BeTrue();
     ////typeReference.Should().BeSameAs(expectedTypeReference.Definition);
     ////typeReference.IsNullable.Should().Be(expectedTypeReference.IsNullable);
     return new AndConstraint<IEdmTypeReference>(typeReference);
 }
        /// <summary>
        /// This method creates and reads the property from the input and 
        /// returns an <see cref="ODataProperty"/> representing the read property.
        /// </summary>
        /// <param name="expectedProperty">The <see cref="IEdmProperty"/> producing the property to be read.</param>
        /// <param name="expectedPropertyTypeReference">The expected type of the property to read.</param>
        /// <returns>An <see cref="ODataProperty"/> representing the read property.</returns>
        internal ODataProperty ReadTopLevelProperty(IEdmStructuralProperty expectedProperty, IEdmTypeReference expectedPropertyTypeReference)
        {
            Debug.Assert(
                expectedPropertyTypeReference == null || !expectedPropertyTypeReference.IsODataEntityTypeKind(),
                "If the expected type is specified it must not be an entity type.");
            Debug.Assert(this.XmlReader != null, "this.xmlReader != null");

            this.ReadPayloadStart();
            Debug.Assert(this.XmlReader.NodeType == XmlNodeType.Element, "The XML reader must be positioned on an Element.");

            // For compatibility with WCF DS Server we need to be able to read the property element in any namespace, not just the OData namespace.
            if (!this.UseServerFormatBehavior && !this.XmlReader.NamespaceEquals(this.XmlReader.ODataMetadataNamespace))
            {
                throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_TopLevelPropertyElementWrongNamespace(this.XmlReader.NamespaceURI, this.XmlReader.ODataMetadataNamespace));
            }

            // this is a top level property so EPM does not apply hence it is safe to say that EPM is not present
            this.AssertRecursionDepthIsZero();
            string expectedPropertyName = ReaderUtils.GetExpectedPropertyName(expectedProperty);
            ODataProperty property = this.ReadProperty(
                true,
                expectedPropertyName,
                expectedPropertyTypeReference,
                /*nullValueReadBehaviorKind*/ ODataNullValueBehaviorKind.Default);
            this.AssertRecursionDepthIsZero();
        
            Debug.Assert(property != null, "If we don't ignore null values the property must not be null.");

            this.ReadPayloadEnd();

            return property;
        }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                throw Error.ArgumentNull("item");
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.IsEntity())
            {
                throw Error.Argument("edmType", SRResources.ArgumentMustBeOfType, EdmTypeKind.Entity);
            }

            ODataEntryWithNavigationLinks entryWrapper = item as ODataEntryWithNavigationLinks;
            if (entryWrapper == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataEntry).Name);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            return ReadEntry(entryWrapper, edmType.AsEntity(), readContext);
        }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return null;
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.IsCollection() || !edmType.AsCollection().ElementType().IsEntity())
            {
                throw Error.Argument("edmType", SRResources.TypeMustBeEntityCollection, edmType.ToTraceString(), typeof(IEdmEntityType).Name);
            }

            IEdmEntityTypeReference elementType = edmType.AsCollection().ElementType().AsEntity();

            ODataFeedWithEntries feed = item as ODataFeedWithEntries;
            if (feed == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataFeedWithEntries).Name);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            return ReadFeed(feed, elementType, readContext);
        }
Example #11
0
        /// <inheritdoc />
        public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer,
            ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }
            if (expectedType == null)
            {
                throw Error.ArgumentNull("expectedType");
            }
            if (graph == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed));
            }

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize
            if (enumerable == null)
            {
                throw new SerializationException(
                    Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
            }

            WriteFeed(enumerable, expectedType, writer, writeContext);
        }
        /// <summary>
        /// This method creates an reads the property from the input and 
        /// returns an <see cref="ODataProperty"/> representing the read property.
        /// </summary>
        /// <param name="expectedPropertyTypeReference">The expected type reference of the property to read.</param>
        /// <returns>A task which returns an <see cref="ODataProperty"/> representing the read property.</returns>
        internal Task<ODataProperty> ReadTopLevelPropertyAsync(IEdmTypeReference expectedPropertyTypeReference)
        {
            Debug.Assert(this.JsonReader.NodeType == JsonNodeType.None, "Pre-Condition: expected JsonNodeType.None, the reader must not have been used yet.");
            this.JsonReader.AssertNotBuffering();

            // We use this to store annotations and check for duplicate annotation names, but we don't really store properties in it.
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();

            return this.ReadPayloadStartAsync(
                ODataPayloadKind.Property,
                duplicatePropertyNamesChecker,
                /*isReadingNestedPayload*/false,
                /*allowEmptyPayload*/false)

                .FollowOnSuccessWith(t =>
                {
                    ODataProperty resultProperty = this.ReadTopLevelPropertyImplementation(expectedPropertyTypeReference, duplicatePropertyNamesChecker);

                    this.ReadPayloadEnd(/*isReadingNestedPayload*/ false);

                    Debug.Assert(this.JsonReader.NodeType == JsonNodeType.EndOfInput, "Post-Condition: expected JsonNodeType.EndOfInput");
                    this.JsonReader.AssertNotBuffering();

                    return resultProperty;
                });
        }
Example #13
0
		public EdmIsTypeExpression(IEdmExpression operand, IEdmTypeReference type)
		{
			EdmUtil.CheckArgumentNull<IEdmExpression>(operand, "operand");
			EdmUtil.CheckArgumentNull<IEdmTypeReference>(type, "type");
			this.operand = operand;
			this.type = type;
		}
Example #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseSingleResult" /> class.
        /// </summary>
        /// <param name="query">The query that returns an object.</param>
        /// <param name="edmType">The EDM type reference of the object.</param>
        /// <param name="context">The context where the action is executed.</param>
        protected BaseSingleResult(IQueryable query, IEdmTypeReference edmType, ApiContext context)
            : base(edmType, context)
        {
            Ensure.NotNull(query, "query");

            this.Result = query.SingleOrDefault();
        }
        /// <inheritdoc />
        public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Entity:
                    return _entityDeserializer;

                case EdmTypeKind.Primitive:
                    return _primitiveDeserializer;

                case EdmTypeKind.Complex:
                    return _complexDeserializer;

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return _feedDeserializer;
                    }
                    else
                    {
                        return _collectionDeserializer;
                    }

                default:
                    return null;
            }
        }
Example #16
0
        /// <summary>
        /// Resolves and validates the Edm type for the given <paramref name="value"/>.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="value">The value in question to resolve the type for.</param>
        /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
        /// <returns>A type for the <paramref name="value"/> or null if no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeNameForValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataValue value, bool isOpenProperty)
        {
            Debug.Assert(model != null, "model != null");
            Debug.Assert(value != null, "value != null");

            ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;
            if (primitiveValue != null)
            {
                Debug.Assert(primitiveValue.Value != null, "primitiveValue.Value != null");
                return EdmLibraryExtensions.GetPrimitiveTypeReference(primitiveValue.Value.GetType());
            }

            ODataComplexValue complexValue = value as ODataComplexValue;
            if (complexValue != null)
            {
                return ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, complexValue.TypeName, EdmTypeKind.Complex, isOpenProperty);
            }

            ODataEnumValue enumValue = value as ODataEnumValue;
            if (enumValue != null)
            {
                return ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, enumValue.TypeName, EdmTypeKind.Enum, isOpenProperty);
            }

            ODataCollectionValue collectionValue = (ODataCollectionValue)value;
            return ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, collectionValue.TypeName, EdmTypeKind.Collection, isOpenProperty);
        }
        public override ODataSerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Primitive:
                    return new ODataPrimitiveSerializer(edmType.AsPrimitive());

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return new ODataFeedSerializer(collectionType, this);
                    }
                    else
                    {
                        return new ODataCollectionSerializer(collectionType, this);
                    }

                case EdmTypeKind.Complex:
                    return new ODataComplexTypeSerializer(edmType.AsComplex(), this);

                case EdmTypeKind.Entity:
                    return new ODataEntityTypeSerializer(edmType.AsEntity(), this);

                default:
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter).Name);
            }
        }
 public EdmStructuredValueSimulator(IEdmTypeReference typeReference, IEnumerable<KeyValuePair<string, IEdmValue>> values)
 {
     this.Type = typeReference;
     this.PropertyValues =
         values.Select(p => new EdmPropertyValue(p.Key, p.Value))
             .ToList();
 }
        /// <summary>
        /// Returns the instance type for the specified Edm type or null if none exists.
        /// </summary>
        /// <param name="type">The type to get the instance type for.</param>
        /// <returns>The instance type for the <paramref name="typeReference"/> or null if no instance type exists.</returns>
        public static Type GetInstanceType(IEdmTypeReference type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            Type result = null;

            if (type.TypeKind() == EdmTypeKind.TypeDefinition)
            {
                var td = type.Definition as IEdmTypeDefinition;
                result = GetUnsignedIntInstanceType(td, type.IsNullable);
            }
            else if (type.TypeKind() == EdmTypeKind.Primitive)
            {
                // TODO: Find out if the type is nullable
                result = GetPrimitiveInstanceType(type.Definition as IEdmPrimitiveType, type.IsNullable);
            }
            else
            {
                // TODO: We should load from DataSource assembly.
                result = GetInstanceType(type.Definition, type.Definition.FullTypeName());
            }

            if (result != null)
            {
                return result;
            }
            else
            {
                throw new InvalidOperationException(string.Format("Cannot find instance type for EdmType {0}.", type.Definition.FullTypeName()));
            }
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="inputContext">The input to read from.</param>
 /// <param name="expectedItemTypeReference">The expected type reference for the items in the collection.</param>
 /// <param name="listener">If not null, the reader will notify the implementer of the interface of relevant state changes in the reader.</param>
 protected ODataCollectionReaderCoreAsync(
     ODataInputContext inputContext,
     IEdmTypeReference expectedItemTypeReference,
     IODataReaderWriterListener listener)
     : base(inputContext, expectedItemTypeReference, listener)
 {
 }
        /// <summary>
        /// Writes the start of a collection.
        /// </summary>
        /// <param name="collectionStart">The collection start to write.</param>
        /// <param name="itemTypeReference">The item type of the collection or null if no metadata is available.</param>
        internal void WriteCollectionStart(ODataCollectionStart collectionStart, IEdmTypeReference itemTypeReference)
        {
            Debug.Assert(collectionStart != null, "collectionStart != null");

            if (this.writingTopLevelCollection)
            {
                // "{"
                this.JsonWriter.StartObjectScope();

                // "@odata.context":...
                this.WriteContextUriProperty(ODataPayloadKind.Collection, () => ODataContextUrlInfo.Create(collectionStart.SerializationInfo, itemTypeReference));

                // "@odata.count":...
                if (collectionStart.Count.HasValue)
                {
                    this.JsonWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataCount);
                    this.JsonWriter.WriteValue(collectionStart.Count.Value);
                }

                // "@odata.nextlink":...
                if (collectionStart.NextPageLink != null)
                {
                    this.JsonWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataNextLink);
                    this.JsonWriter.WriteValue(this.UriToString(collectionStart.NextPageLink));
                }

                // "value":
                this.JsonWriter.WriteValuePropertyName();
            }

            // Write the start of the array for the collection items
            // "["
            this.JsonWriter.StartArrayScope();
        }
Example #22
0
 private static EdmTypeKind ComputeTargetTypeKind(IEdmTypeReference expectedTypeReference, bool forEntityValue, string payloadTypeName, EdmTypeKind payloadTypeKind, ODataMessageReaderSettings messageReaderSettings, Func<EdmTypeKind> typeKindFromPayloadFunc)
 {
     EdmTypeKind kind;
     bool flag = (messageReaderSettings.ReaderBehavior.TypeResolver != null) && (payloadTypeKind != EdmTypeKind.None);
     if (((expectedTypeReference != null) && !flag) && (!expectedTypeReference.IsODataPrimitiveTypeKind() || !messageReaderSettings.DisablePrimitiveTypeConversion))
     {
         kind = expectedTypeReference.TypeKind();
     }
     else if (payloadTypeKind != EdmTypeKind.None)
     {
         if (!forEntityValue)
         {
             ValidationUtils.ValidateValueTypeKind(payloadTypeKind, payloadTypeName);
         }
         kind = payloadTypeKind;
     }
     else
     {
         kind = typeKindFromPayloadFunc();
     }
     if (ShouldValidatePayloadTypeKind(messageReaderSettings, expectedTypeReference, payloadTypeKind))
     {
         ValidationUtils.ValidateTypeKind(kind, expectedTypeReference.TypeKind(), payloadTypeName);
     }
     return kind;
 }
        /// <summary>
        /// Returns true if the compared type reference is semantically equivalent to this type reference.
        /// Schema types (<see cref="IEdmSchemaType"/>) are compared by their object refs.
        /// </summary>
        /// <param name="thisType">Type reference being compared.</param>
        /// <param name="otherType">Type referenced being compared to.</param>
        /// <returns>Equivalence of the two type references.</returns>
        public static bool IsEquivalentTo(this IEdmTypeReference thisType, IEdmTypeReference otherType)
        {
            if (thisType == otherType)
            {
                return true;
            }
            
            if (thisType == null || otherType == null)
            {
                return false;
            }

            EdmTypeKind typeKind = thisType.TypeKind();
            if (typeKind != otherType.TypeKind())
            {
                return false;
            }

            if (typeKind == EdmTypeKind.Primitive)
            {
                return ((IEdmPrimitiveTypeReference)thisType).IsEquivalentTo((IEdmPrimitiveTypeReference)otherType);
            }
            else
            {
                return thisType.IsNullable == otherType.IsNullable &&
                       thisType.Definition.IsEquivalentTo(otherType.Definition);
            }
        }
        protected override ODataEntryDeserializer CreateDeserializer(IEdmTypeReference edmType)
        {
            if (edmType != null)
            {
                switch (edmType.TypeKind())
                {
                    case EdmTypeKind.Entity:
                        return new ODataEntityDeserializer(edmType.AsEntity(), this);

                    case EdmTypeKind.Primitive:
                        return new ODataPrimitiveDeserializer(edmType.AsPrimitive());

                    case EdmTypeKind.Complex:
                        return new ODataComplexTypeDeserializer(edmType.AsComplex(), this);

                    case EdmTypeKind.Collection:
                        IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                        if (collectionType.ElementType().IsEntity())
                        {
                            return new ODataFeedDeserializer(collectionType, this);
                        }
                        else
                        {
                            return new ODataCollectionDeserializer(collectionType, this);
                        }
                }
            }

            return null;
        }
        /// <summary>
        /// Writes the given object specified by the parameter graph as a part of an existing OData message using the given
        /// messageWriter and the writeContext.
        /// </summary>
        /// <param name="graph">The object to be written.</param>
        /// <param name="expectedType">The expected EDM type of the object represented by <paramref name="graph"/>.</param>
        /// <param name="writer">The <see cref="ODataDeltaWriter" /> to be used for writing.</param>
        /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
        public virtual async Task WriteDeltaFeedInlineAsync(object graph, IEdmTypeReference expectedType, ODataDeltaWriter writer,
            ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }
            if (expectedType == null)
            {
                throw Error.ArgumentNull("expectedType");
            }
            if (graph == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize
            if (enumerable == null)
            {
                throw new SerializationException(
                    Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
            }

            await WriteFeedAsync(enumerable, expectedType, writer, writeContext);
        }
        /// <summary>
        /// Try to parse the given text by each parser.
        /// </summary>
        /// <param name="text">Part of the Uri which has to be parsed to a value of EdmType <paramref name="targetType"/></param>
        /// <param name="targetType">The type which the uri text has to be parsed to</param>
        /// <param name="parsingException">Assign the exception only in case the text could be parsed to the <paramref name="targetType"/> but failed during the parsing process</param>
        /// <returns>If the parsing proceess has succeeded, returns the parsed object, otherwise returns 'Null'</returns>
        public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException)
        {
            parsingException = null;
            object targetValue;

            // Try to parse the uri text with each parser
            foreach (IUriLiteralParser uriTypeParser in uriTypeParsers)
            {
                targetValue = uriTypeParser.ParseUriStringToType(text, targetType, out parsingException);

                // Stop in case the parser has returned an excpetion
                if (parsingException != null)
                {
                    return null;
                }

                // In case of no exception and no value - The parse cannot parse the given text
                if (targetValue != null)
                {
                    return targetValue;
                }
            }

            return null;
        }
        internal static object ConvertValue(
            object odataValue,
            string parameterName,
            Type expectedReturnType,
            IEdmTypeReference propertyType,
            IEdmModel model,
            HttpRequestMessage request,
            IServiceProvider serviceProvider)
        {
            var readContext = new ODataDeserializerContext
            {
                Model = model,
                Request = request
            };

            // Enum logic can be removed after RestierEnumDeserializer extends ODataEnumDeserializer
            var deserializerProvider = serviceProvider.GetService<ODataDeserializerProvider>();
            var enumValue = odataValue as ODataEnumValue;
            if (enumValue != null)
            {
                ODataEdmTypeDeserializer deserializer
                    = deserializerProvider.GetEdmTypeDeserializer(propertyType.AsEnum());
                return deserializer.ReadInline(enumValue, propertyType, readContext);
            }

            var returnValue = ODataModelBinderConverter.Convert(
                odataValue, propertyType, expectedReturnType, parameterName, readContext, serviceProvider);

            if (!propertyType.IsCollection())
            {
                return returnValue;
            }

            return ConvertCollectionType(returnValue, expectedReturnType);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmCollectionExpression"/> class.
        /// </summary>
        /// <param name="declaredType">Declared type of the collection.</param>
        /// <param name="elements">The constructed element values.</param>
        public EdmCollectionExpression(IEdmTypeReference declaredType, IEnumerable<IEdmExpression> elements)
        {
            EdmUtil.CheckArgumentNull(elements, "elements");

            this.declaredType = declaredType;
            this.elements = elements;
        }
 public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
 {
     if (graph != null)
     {
         base.WriteObjectInline(graph, expectedType, writer, writeContext);
     }
 }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return null;
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                    Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference elementType = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            return ReadCollectionValue(collection, elementType, readContext);
        }
Example #31
0
 /// <summary>
 /// Creates a new instance of the type annotation for a collection value.
 /// </summary>
 /// <param name="collectionType">The type of the collection value (required).</param>
 public ODataTypeAnnotation(IEdmCollectionTypeReference collectionType)
 {
     ExceptionUtils.CheckArgumentNotNull(collectionType, "collectionType");
     this.type = collectionType;
 }
Example #32
0
        public void WriteCollectionValue(ODataCollectionValue collectionValue, IEdmTypeReference metadataTypeReference, bool isTopLevelProperty, bool isInUri, bool isOpenPropertyType)
        {
            Debug.Assert(collectionValue != null, "collectionValue != null");
            Debug.Assert(!isTopLevelProperty || !isInUri, "Cannot be a top level property and in a uri");

            this.IncreaseRecursionDepth();

            // If the CollectionValue has type information write out the metadata and the type in it.
            string typeName = collectionValue.TypeName;

            if (isTopLevelProperty)
            {
                Debug.Assert(metadataTypeReference == null, "Never expect a metadata type for top-level properties.");
                if (typeName == null)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightValueSerializer_MissingTypeNameOnCollection);
                }
            }
            else
            {
                // In requests, we allow the metadata type reference to be null if the type name is specified in the OM
                if (metadataTypeReference == null && !this.WritingResponse && typeName == null && this.Model.IsUserModel())
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueSerializer_NoExpectedTypeOrTypeNameSpecifiedForCollectionValueInRequest);
                }
            }

            // resolve the type name to the type; if no type name is specified we will use the
            // type inferred from metadata
            IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)TypeNameOracle.ResolveAndValidateTypeNameForValue(this.Model, metadataTypeReference, collectionValue, isOpenPropertyType);

            typeName = this.JsonLightOutputContext.TypeNameOracle.GetValueTypeNameForWriting(collectionValue, metadataTypeReference, collectionTypeReference, isOpenPropertyType);
            bool useValueProperty = isInUri && !string.IsNullOrEmpty(typeName);

            if (useValueProperty)
            {
                // "{"
                this.JsonWriter.StartObjectScope();
                ODataJsonLightWriterUtils.WriteODataTypeInstanceAnnotation(this.JsonWriter, typeName);
                this.JsonWriter.WriteValuePropertyName();
            }

            // [
            // This represents the array of items in the CollectionValue
            this.JsonWriter.StartArrayScope();

            // Iterate through the CollectionValue items and write them out (treat null Items as an empty enumeration)
            IEnumerable items = collectionValue.Items;

            if (items != null)
            {
                IEdmTypeReference expectedItemTypeReference = collectionTypeReference == null ? null : collectionTypeReference.ElementType();

                DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = null;
                foreach (object item in items)
                {
                    ValidationUtils.ValidateCollectionItem(item, expectedItemTypeReference.IsNullable());

                    ODataComplexValue itemAsComplexValue = item as ODataComplexValue;
                    if (itemAsComplexValue != null)
                    {
                        if (duplicatePropertyNamesChecker == null)
                        {
                            duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();
                        }

                        this.WriteComplexValue(
                            itemAsComplexValue,
                            expectedItemTypeReference,
                            false /*isTopLevel*/,
                            false /*isOpenPropertyType*/,
                            duplicatePropertyNamesChecker);

                        duplicatePropertyNamesChecker.Clear();
                    }
                    else
                    {
                        Debug.Assert(!(item is ODataCollectionValue), "!(item is ODataCollectionValue)");
                        Debug.Assert(!(item is ODataStreamReferenceValue), "!(item is ODataStreamReferenceValue)");

                        // by design: collection element's type name is not written for enum or non-spatial primitive value even in case of full metadata.
                        // because enum and non-spatial primitive types don't have inheritance, the type of each element is the same as the item type of the collection, whose type name for spatial types in full metadata mode.
                        ODataEnumValue enumValue = item as ODataEnumValue;
                        if (enumValue != null)
                        {
                            this.WriteEnumValue(enumValue, expectedItemTypeReference);
                        }
                        else
                        {
                            if (item != null)
                            {
                                this.WritePrimitiveValue(item, expectedItemTypeReference);
                            }
                            else
                            {
                                this.WriteNullValue();
                            }
                        }
                    }
                }
            }

            // End the array scope which holds the items
            this.JsonWriter.EndArrayScope();

            if (useValueProperty)
            {
                this.JsonWriter.EndObjectScope();
            }

            this.DecreaseRecursionDepth();
        }
Example #33
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RawResult" /> class.
 /// </summary>
 /// <param name="query">The query that returns a primitive value.</param>
 /// <param name="edmType">The EDM type reference of the primitive value.</param>
 public RawResult(IQueryable query, IEdmTypeReference edmType)
     : base(query, edmType)
 {
 }
Example #34
0
 /// <summary>
 /// Creates a new instance of the type annotation for an entity value.
 /// </summary>
 /// <param name="navigationSource">The navigation source the entity belongs to (required).</param>
 /// <param name="entityType">The entity type of the entity value if not the base type of the entity set (optional).</param>
 public ODataTypeAnnotation(IEdmNavigationSource navigationSource, IEdmEntityType entityType)
 {
     ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
     this.navigationSource = navigationSource;
     this.type             = entityType.ToTypeReference(/*isNullable*/ true);
 }
Example #35
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmFunction"/> class.
 /// </summary>
 /// <param name="namespaceName">Namespace of the function.</param>
 /// <param name="name">Name of the function.</param>
 /// <param name="returnType">Return type of the function.</param>
 public EdmFunction(string namespaceName, string name, IEdmTypeReference returnType)
     : this(namespaceName, name, returnType, null)
 {
 }
Example #36
0
        public void WriteComplexValue(
            ODataComplexValue complexValue,
            IEdmTypeReference metadataTypeReference,
            bool isTopLevel,
            bool isOpenPropertyType,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            Debug.Assert(complexValue != null, "complexValue != null");

            this.IncreaseRecursionDepth();

            // Start the object scope which will represent the entire complex instance;
            // for top-level complex properties we already wrote the object scope (and the context URI when needed).
            if (!isTopLevel)
            {
                this.JsonWriter.StartObjectScope();
            }

            string typeName = complexValue.TypeName;

            if (isTopLevel)
            {
                Debug.Assert(metadataTypeReference == null, "Never expect a metadata type for top-level properties.");
                if (typeName == null)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightValueSerializer_MissingTypeNameOnComplex);
                }
            }
            else
            {
                // In requests, we allow the property type reference to be null if the type name is specified in the OM
                if (metadataTypeReference == null && !this.WritingResponse && typeName == null && this.Model.IsUserModel())
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueSerializer_NoExpectedTypeOrTypeNameSpecifiedForComplexValueRequest);
                }
            }

            // Resolve the type name to the type; if no type name is specified we will use the
            // type inferred from metadata.
            IEdmComplexTypeReference complexValueTypeReference = (IEdmComplexTypeReference)TypeNameOracle.ResolveAndValidateTypeNameForValue(this.Model, metadataTypeReference, complexValue, isOpenPropertyType);

            Debug.Assert(
                metadataTypeReference == null || complexValueTypeReference == null || EdmLibraryExtensions.IsAssignableFrom(metadataTypeReference, complexValueTypeReference),
                "Complex property types must be the same as or inherit from the ones from metadata (unless open).");

            typeName = this.JsonLightOutputContext.TypeNameOracle.GetValueTypeNameForWriting(complexValue, metadataTypeReference, complexValueTypeReference, isOpenPropertyType);
            if (typeName != null)
            {
                ODataJsonLightWriterUtils.WriteODataTypeInstanceAnnotation(this.JsonWriter, typeName);
            }

            // Write custom instance annotations
            this.InstanceAnnotationWriter.WriteInstanceAnnotations(complexValue.InstanceAnnotations);

            // Write the properties of the complex value as usual. Note we do not allow complex types to contain named stream properties.
            this.PropertySerializer.WriteProperties(
                complexValueTypeReference == null ? null : complexValueTypeReference.ComplexDefinition(),
                complexValue.Properties,
                true /* isComplexValue */,
                duplicatePropertyNamesChecker,
                null /*projectedProperties */);

            // End the object scope which represents the complex instance;
            // for top-level complex properties we already wrote the end object scope.
            if (!isTopLevel)
            {
                this.JsonWriter.EndObjectScope();
            }

            this.DecreaseRecursionDepth();
        }
Example #37
0
        private void VerifyPrimitiveValueDoesNotRoundtrip(object clrValue, IEdmTypeReference typeReference, ODataVersion version, string description, bool isIeee754Compatible)
        {
            var actualValue = this.WriteThenReadValue(clrValue, typeReference, version, isIeee754Compatible);

            actualValue.Should().NotBe(clrValue, description);
        }
 /// <summary>
 /// Gets the <see cref="ODataEdmTypeDeserializer"/> for the given EDM type.
 /// </summary>
 /// <param name="edmType">The EDM type.</param>
 /// <returns>An <see cref="ODataEdmTypeDeserializer"/> that can deserialize the given EDM type.</returns>
 public abstract ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType);
 protected ODataEntryDeserializer(IEdmTypeReference edmType, ODataPayloadKind payloadKind, ODataDeserializerProvider deserializerProvider)
     : this(edmType, payloadKind)
 {
     DeserializerProvider = deserializerProvider;
 }
Example #40
0
        private object WriteThenReadValue(object clrValue, IEdmTypeReference typeReference, ODataVersion version, bool isIeee754Compatible)
        {
            var stream = new MemoryStream();

            var settings = new ODataMessageWriterSettings {
                Version = version
            };

            settings.SetServiceDocumentUri(new Uri("http://odata.org/test/"));

            var mediaType = isIeee754Compatible
                ? new ODataMediaType("application", "json", new KeyValuePair <string, string>("IEEE754Compatible", "true"))
                : new ODataMediaType("application", "json");

            var messageInfoForWriter = new ODataMessageInfo
            {
                MessageStream = new NonDisposingStream(stream),
                MediaType     = mediaType,
                Encoding      = Encoding.UTF8,
                IsResponse    = true,
                IsAsync       = false,
                Model         = this.model,
                Container     = this.container
            };

            using (var outputContext = new ODataJsonLightOutputContext(messageInfoForWriter, settings))
            {
                var serializer = new ODataJsonLightValueSerializer(outputContext);
                serializer.WritePrimitiveValue(clrValue, typeReference);
            }

            stream.Position = 0;

            var messageInfoForReader = new ODataMessageInfo
            {
                Encoding      = Encoding.UTF8,
                IsResponse    = true,
                MediaType     = mediaType,
                IsAsync       = false,
                Model         = this.model,
                MessageStream = stream,
                Container     = this.container
            };

            object actualValue;

            using (var inputContext = new ODataJsonLightInputContext(
                       messageInfoForReader, new ODataMessageReaderSettings()))
            {
                var deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext);
                deserializer.JsonReader.Read();
                actualValue = deserializer.ReadNonEntityValue(
                    /*payloadTypeName*/ null,
                    typeReference,
                    /*propertyAndAnnotationCollector*/ null,
                    /*collectionValidator*/ null,
                    /*validateNullValue*/ true,
                    /*isTopLevel*/ true,
                    /*insideResourceValue*/ false,
                    /*propertyName*/ null);
            }

            return(actualValue);
        }
 /// <summary>
 /// Deserializes the item into a new object of type corresponding to <paramref name="edmType"/>.
 /// </summary>
 /// <param name="item">The item to deserialize.</param>
 /// <param name="edmType">The EDM type of the object to read into.</param>
 /// <param name="readContext">The <see cref="ODataDeserializerContext"/>.</param>
 /// <returns>The deserialized object.</returns>
 public virtual object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
 {
     throw Error.NotSupported(SRResources.DoesNotSupportReadInLine, GetType().Name);
 }
Example #42
0
 private void VerifyPrimitiveValueRoundtrips(object clrValue, IEdmTypeReference typeReference, ODataVersion version, string description, bool isIeee754Compatible)
 {
     VerifyPrimitiveValueRoundtrips(clrValue, typeReference, version, description, isIeee754Compatible, clrValue);
 }
Example #43
0
 internal Scope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmTypeReference expectedResourceTypeReference, ODataUri odataUri)
     : this(state, item, odataUri)
 {
     this.NavigationSource      = navigationSource;
     this.ResourceTypeReference = expectedResourceTypeReference;
 }
        private static object ConvertCollectionValue(ODataCollectionValue collection, IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider, ODataDeserializerReadContext readContext)
        {
            IEdmCollectionType collectionType = propertyType as IEdmCollectionType;

            Contract.Assert(collectionType != null, "The type for collection must be a IEdmCollectionType.");

            IList collectionList = CreateNewCollection();

            RecurseEnter(readContext);

            Contract.Assert(collection.Items != null, "The ODataLib reader should always populate the ODataCollectionValue.Items collection.");
            foreach (object odataItem in collection.Items)
            {
                IEdmTypeReference itemType = collectionType.ElementType;
                collectionList.Add(ConvertValue(odataItem, ref itemType, deserializerProvider, readContext));
            }

            RecurseLeave(readContext);

            return(collectionList);
        }
Example #45
0
        /// <summary>
        /// Converts the given <paramref name="value"/> to a corresponding CLR type. Expects the
        /// <paramref name="value"/> to have already been properly unescaped from an actual Uri.
        /// </summary>
        /// <param name="value">Value from a Uri to be converted.</param>
        /// <param name="version">Version to be compliant with.</param>
        /// <param name="model">Optional model to perform verification against.</param>
        /// <param name="typeReference">Optional IEdmTypeReference to perform verification against.
        ///  Callers must provide a <paramref name="model"/> containing this type if it is specified.</param>
        /// <returns>A CLR object that the <paramref name="value"/> represents.</returns>
        public static object ConvertFromUriLiteral(string value, ODataVersion version, IEdmModel model, IEdmTypeReference typeReference)
        {
            ExceptionUtils.CheckArgumentNotNull(value, "value");
            if (typeReference != null && model == null)
            {
                throw new ODataException(ODataErrorStrings.ODataUriUtils_ConvertFromUriLiteralTypeRefWithoutModel);
            }

            if (model == null)
            {
                model = Microsoft.Data.Edm.Library.EdmCoreModel.Instance;
            }

            // Let ExpressionLexer try to get a primitive
            ExpressionLexer lexer = new ExpressionLexer(value, false /*moveToFirstToken*/, false /*useSemicolonDelimeter*/);
            Exception       error;
            ExpressionToken token;

            lexer.TryPeekNextToken(out token, out error);

            if (token.Kind == ExpressionTokenKind.BracketedExpression)
            {
                // Should be a complex or collection value
                return(ODataUriConversionUtils.ConvertFromComplexOrCollectionValue(value, version, model, typeReference));
            }

            object result = lexer.ReadLiteralToken();

            // If we have a typeReference then perform verification and convert if necessary
            if (typeReference != null)
            {
                result = ODataUriConversionUtils.VerifyAndCoerceUriPrimitiveLiteral(result, model, typeReference, version);
            }

            if (result is ISpatial)
            {
                ODataVersionChecker.CheckSpatialValue(version);
            }

            return(result);
        }
Example #46
0
 /// <summary>
 /// Constructor creating a new reader scope.
 /// </summary>
 /// <param name="state">The reader state of this scope.</param>
 /// <param name="item">The item attached to this scope.</param>
 /// <param name="navigationSource">The navigation source we are going to read entities for.</param>
 /// <param name="expectedResourceType">The expected resource type for the scope.</param>
 /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param>
 internal StreamScope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmTypeReference expectedResourceType, ODataUri odataUri)
     : base(state, item, navigationSource, expectedResourceType, odataUri)
 {
     this.StreamingState = StreamingState.None;
 }
 /// <inheritdoc/>
 public override void PromoteBinaryOperandTypes(BinaryOperatorKind binaryOperatorKind,
                                                ref SingleValueNode leftNode, ref SingleValueNode rightNode, out IEdmTypeReference typeReference)
 {
     _stringAsEnum.PromoteBinaryOperandTypes(binaryOperatorKind, ref leftNode, ref rightNode, out typeReference);
 }
        private object ReadNestedResourceSetInline(ODataResourceSetWrapper resourceSetWrapper, IEdmTypeReference edmType,
                                                   ODataDeserializerContext readContext)
        {
            Contract.Assert(resourceSetWrapper != null);
            Contract.Assert(edmType != null);
            Contract.Assert(readContext != null);

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmType);

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

            IEdmStructuredTypeReference structuredType = edmType.AsCollection().ElementType().AsStructured();
            var nestedReadContext = new ODataDeserializerContext
            {
                Path     = readContext.Path,
                Model    = readContext.Model,
                Request  = readContext.Request,
                TimeZone = readContext.TimeZone
            };

            if (readContext.IsNoClrType)
            {
                if (structuredType.IsEntity())
                {
                    nestedReadContext.ResourceType = typeof(EdmEntityObjectCollection);
                }
                else
                {
                    nestedReadContext.ResourceType = typeof(EdmComplexObjectCollection);
                }
            }
            else
            {
                Type clrType = readContext.Model.GetClrType(structuredType);

                if (clrType == null)
                {
                    throw new ODataException(
                              Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName()));
                }

                nestedReadContext.ResourceType = typeof(List <>).MakeGenericType(clrType);
            }

            return(deserializer.ReadInline(resourceSetWrapper, edmType, nestedReadContext));
        }