Example #1
0
        /// <summary>
        /// Constructs an ODataMetadataContext.
        /// </summary>
        /// <param name="isResponse">true if we are reading a response payload, false otherwise.</param>
        /// <param name="operationsBoundToEntityTypeMustBeContainerQualified">Callback to determine whether operations bound to this type must be qualified with the operation they belong to when appearing in a $select clause.</param>
        /// <param name="edmTypeResolver">EdmTypeResolver instance to resolve entity set base type.</param>
        /// <param name="model">The Edm model.</param>
        /// <param name="metadataDocumentUri">The metadata document Uri.</param>
        /// <remarks>This overload should only be used by the reader.</remarks>
        public ODataMetadataContext(bool isResponse, Func <IEdmEntityType, bool> operationsBoundToEntityTypeMustBeContainerQualified, EdmTypeResolver edmTypeResolver, IEdmModel model, Uri metadataDocumentUri)
        {
            Debug.Assert(edmTypeResolver != null, "edmTypeResolver != null");
            Debug.Assert(model != null, "model != null");

            this.isResponse = isResponse;
            this.operationsBoundToEntityTypeMustBeContainerQualified = operationsBoundToEntityTypeMustBeContainerQualified ?? EdmLibraryExtensions.OperationsBoundToEntityTypeMustBeContainerQualified;
            this.edmTypeResolver               = edmTypeResolver;
            this.model                         = model;
            this.metadataDocumentUri           = metadataDocumentUri;
            this.alwaysBindableOperationsCache = new Dictionary <IEdmType, IEdmFunctionImport[]>(ReferenceEqualityComparer <IEdmType> .Instance);
        }
Example #2
0
        /// <summary>
        /// Constructs an ODataMetadataContext.
        /// </summary>
        /// <param name="isResponse">true if we are reading a response payload, false otherwise.</param>
        /// <param name="operationsBoundToEntityTypeMustBeContainerQualified">Callback to determine whether operations bound to this type must be qualified with the operation they belong to when appearing in a $select clause.</param>
        /// <param name="edmTypeResolver">EdmTypeResolver instance to resolve entity set base type.</param>
        /// <param name="model">The Edm model.</param>
        /// <param name="metadataDocumentUri">The metadata document Uri.</param>
        /// <param name="odataUri">The request Uri.</param>
        /// <param name="metadataLevel">Current Json Light MetadataLevel</param>
        /// <remarks>This overload should only be used by the reader.</remarks>
        public ODataMetadataContext(
            bool isResponse,
            Func <IEdmEntityType, bool> operationsBoundToEntityTypeMustBeContainerQualified,
            EdmTypeResolver edmTypeResolver,
            IEdmModel model,
            Uri metadataDocumentUri,
            ODataUri odataUri,
            JsonLightMetadataLevel metadataLevel)
            : this(isResponse, operationsBoundToEntityTypeMustBeContainerQualified, edmTypeResolver, model, metadataDocumentUri, odataUri)
        {
            Debug.Assert(metadataLevel != null, "MetadataLevel != null");

            this.metadataLevel = metadataLevel;
        }
        /// <summary>
        /// Parses the fragment of an entity reference link metadata URI.
        /// </summary>
        /// <param name="edmTypeResolver">Edm Type Resolver used to get the ElementType of the entity set.</param>
        /// <param name="entitySet">Entity Set used as a starting point to find the navigation property</param>
        /// <param name="typeName">The name of the type declaring the navigation property.</param>
        /// <param name="propertyName">The name of the navigation property.</param>
        /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param>
        /// <param name="version">The version of the payload being read.</param>
        /// <returns>The resolved navigation property.</returns>
        private IEdmNavigationProperty ResolveEntityReferenceLinkMetadataFragment(EdmTypeResolver edmTypeResolver, IEdmEntitySet entitySet, string typeName, string propertyName, ODataReaderBehavior readerBehavior, ODataVersion version)
        {
            //// {entitySet}/$links/{nav-property}
            //// {entitySet}/$links/{nav-property}/@Element
            //// {entitySet}/typeName/$links/{nav-property}
            //// {entitySet}/typeName/$links/{nav-property}/@Element
            IEdmEntityType edmEntityType = edmTypeResolver.GetElementType(entitySet);

            if (typeName != null)
            {
                edmEntityType = this.ResolveTypeCast(entitySet, typeName, readerBehavior, version, edmEntityType);
            }

            IEdmNavigationProperty navigationProperty = this.ResolveNavigationProperty(edmEntityType, propertyName);

            return(navigationProperty);
        }
        /// <summary>
        /// Constructs an ODataMetadataContext.
        /// </summary>
        /// <param name="isResponse">true if we are reading a response payload, false otherwise.</param>
        /// <param name="operationsBoundToStructuredTypeMustBeContainerQualified">Callback to determine whether operations bound to this type must be qualified with the operation they belong to when appearing in a $select clause.</param>
        /// <param name="edmTypeResolver">EdmTypeResolver instance to resolve entity set base type.</param>
        /// <param name="model">The Edm model.</param>
        /// <param name="metadataDocumentUri">The metadata document Uri.</param>
        /// <param name="odataUri">The request Uri.</param>
        /// <remarks>This overload should only be used by the reader.</remarks>
        public ODataMetadataContext(
            bool isResponse,
            Func <IEdmStructuredType, bool> operationsBoundToStructuredTypeMustBeContainerQualified,
            EdmTypeResolver edmTypeResolver,
            IEdmModel model,
            Uri metadataDocumentUri,
            ODataUri odataUri)
        {
            Debug.Assert(edmTypeResolver != null, "edmTypeResolver != null");
            Debug.Assert(model != null, "model != null");

            this.isResponse = isResponse;
            this.operationsBoundToStructuredTypeMustBeContainerQualified = operationsBoundToStructuredTypeMustBeContainerQualified ?? EdmLibraryExtensions.OperationsBoundToStructuredTypeMustBeContainerQualified;
            this.edmTypeResolver     = edmTypeResolver;
            this.model               = model;
            this.metadataDocumentUri = metadataDocumentUri;
            this.odataUri            = odataUri;
        }
Example #5
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        protected ODataOutputContext(
            ODataFormat format,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            this.format = format;
            this.messageWriterSettings = messageWriterSettings;
            this.writingResponse       = writingResponse;
            this.synchronous           = synchronous;
            this.model           = model ?? EdmCoreModel.Instance;
            this.urlResolver     = urlResolver;
            this.edmTypeResolver = EdmTypeWriterResolver.Instance;
        }
Example #6
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this input context.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        protected ODataInputContext(
            ODataFormat format,
            ODataMessageReaderSettings messageReaderSettings,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");

            this.format = format;
            this.messageReaderSettings = messageReaderSettings;
            this.readingResponse       = readingResponse;
            this.synchronous           = synchronous;
            this.model           = model;
            this.urlResolver     = urlResolver;
            this.edmTypeResolver = new EdmTypeReaderResolver(this.Model, this.MessageReaderSettings.ReaderBehavior);
        }
Example #7
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this input context.</param>
        /// <param name="messageInfo">The context information for the message.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        protected ODataInputContext(
            ODataFormat format,
            ODataMessageInfo messageInfo,
            ODataMessageReaderSettings messageReaderSettings)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageInfo, "messageInfo");
            ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");

            this.format = format;
            this.messageReaderSettings = messageReaderSettings;
            this.readingResponse       = messageInfo.IsResponse;
            this.synchronous           = !messageInfo.IsAsync;
            this.model = messageInfo.Model ?? EdmCoreModel.Instance;
            this.payloadUriConverter    = messageInfo.PayloadUriConverter;
            this.container              = messageInfo.Container;
            this.edmTypeResolver        = new EdmTypeReaderResolver(this.Model, this.MessageReaderSettings.ClientCustomTypeResolver);
            this.payloadValueConverter  = ODataPayloadValueConverter.GetPayloadValueConverter(this.container);
            this.odataSimplifiedOptions = ODataSimplifiedOptions.GetODataSimplifiedOptions(this.container, messageReaderSettings.Version);
        }
Example #8
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageInfo">The context information for the message.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        protected ODataOutputContext(
            ODataFormat format,
            ODataMessageInfo messageInfo,
            ODataMessageWriterSettings messageWriterSettings)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            this.format = format;
            this.messageWriterSettings = messageWriterSettings;
            this.writingResponse       = messageInfo.IsResponse;
            this.synchronous           = !messageInfo.IsAsync;
            this.model = messageInfo.Model ?? EdmCoreModel.Instance;
            this.payloadUriConverter    = messageInfo.PayloadUriConverter;
            this.container              = messageInfo.Container;
            this.edmTypeResolver        = EdmTypeWriterResolver.Instance;
            this.payloadValueConverter  = ODataPayloadValueConverter.GetPayloadValueConverter(this.container);
            this.writerValidator        = messageWriterSettings.Validator;
            this.odataSimplifiedOptions = ODataSimplifiedOptions.GetODataSimplifiedOptions(this.container);
        }
Example #9
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        protected ODataOutputContext(
            ODataFormat format,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            this.format = format;
            this.messageWriterSettings = messageWriterSettings;
            this.writingResponse       = writingResponse;
            this.synchronous           = synchronous;
            this.model                 = model ?? EdmCoreModel.Instance;
            this.urlResolver           = urlResolver;
            this.edmTypeResolver       = EdmTypeWriterResolver.Instance;
            this.payloadValueConverter = this.model.GetPayloadValueConverter();
            this.writerValidator       = ValidatorFactory.CreateWriterValidator(messageWriterSettings.EnableFullValidation);
        }
        /// <summary>
        /// Returns the parse results of the metadata uri if it has a AssociationLink in the uri
        /// </summary>
        /// <param name="edmTypeResolver">Edm Type Resolver to determine entityset type element.</param>
        /// <param name="partCount">Number of split parts the metadata fragment is split into.</param>
        /// <param name="parts">The  actual metadata fragment parts.</param>
        /// <param name="readerBehavior">The reader behavior.</param>
        /// <param name="version">The odata version.</param>
        /// <returns>Returns with an EntityReferenceLink or Links depending on the Uri, sets the parse results with the navigation, and set</returns>
        private ODataPayloadKind ParseAssociationLinks(EdmTypeResolver edmTypeResolver, int partCount, string[] parts, ODataReaderBehavior readerBehavior, ODataVersion version)
        {
            return(this.ResolveEntitySet(
                       parts[0],
                       (IEdmEntitySet resolvedEntitySet) =>
            {
                ODataPayloadKind detectedPayloadKind = ODataPayloadKind.Unsupported;
                IEdmNavigationProperty navigationProperty;
                switch (partCount)
                {
                case 3:
                    if (string.CompareOrdinal(ODataConstants.AssociationLinkSegmentName, parts[1]) == 0)
                    {
                        // Entity reference links: {schema.entity-container.entity-set}/$links/{nav-property}
                        navigationProperty = this.ResolveEntityReferenceLinkMetadataFragment(edmTypeResolver, resolvedEntitySet, (string)null, parts[2], readerBehavior, version);
                        detectedPayloadKind = this.SetEntityLinkParseResults(navigationProperty, null);
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_InvalidAssociationLink(UriUtilsCommon.UriToString(this.parseResult.MetadataUri)));
                    }

                    break;

                case 4:
                    if (string.CompareOrdinal(ODataConstants.AssociationLinkSegmentName, parts[1]) == 0)
                    {
                        // Entry with property: {schema.entity-container.entity-set}/$links/{col-nav-property}/@Element
                        // Entry with property: {schema.entity-container.entity-set}/$links/{ref-nav-property}/@Element (invalid, will throw)
                        navigationProperty = this.ResolveEntityReferenceLinkMetadataFragment(edmTypeResolver, resolvedEntitySet, null, parts[2], readerBehavior, version);
                        this.ValidateLinkMetadataUriFragmentItemSelector(parts[3]);
                        detectedPayloadKind = this.SetEntityLinkParseResults(navigationProperty, parts[3]);
                    }
                    else if (string.CompareOrdinal(ODataConstants.AssociationLinkSegmentName, parts[2]) == 0)
                    {
                        // Entry with property: {schema.entity-container.entity-set}/type/$links/{colproperty}
                        navigationProperty = this.ResolveEntityReferenceLinkMetadataFragment(edmTypeResolver, resolvedEntitySet, parts[1], parts[3], readerBehavior, version);
                        detectedPayloadKind = this.SetEntityLinkParseResults(navigationProperty, null);
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_InvalidAssociationLink(UriUtilsCommon.UriToString(this.parseResult.MetadataUri)));
                    }

                    break;

                case 5:
                    if (string.CompareOrdinal(ODataConstants.AssociationLinkSegmentName, parts[2]) == 0)
                    {
                        // Entry with property: {schema.entity-container.entity-set}/type/$links/{navproperty}/@Element
                        navigationProperty = this.ResolveEntityReferenceLinkMetadataFragment(edmTypeResolver, resolvedEntitySet, parts[1], parts[3], readerBehavior, version);
                        this.ValidateLinkMetadataUriFragmentItemSelector(parts[2]);
                        detectedPayloadKind = this.SetEntityLinkParseResults(navigationProperty, parts[4]);
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_InvalidAssociationLink(UriUtilsCommon.UriToString(this.parseResult.MetadataUri)));
                    }

                    break;

                default:
                    throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_InvalidAssociationLink(UriUtilsCommon.UriToString(this.parseResult.MetadataUri)));
                }

                return detectedPayloadKind;
            }));
        }