Пример #1
0
 /// <summary>
 /// Constructs an instance of <see cref="ODataEntryMetadataContextWithoutModel"/>.
 /// </summary>
 /// <param name="entry">The entry instance.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
 /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param>
 internal ODataEntryMetadataContextWithoutModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo)
     : base(entry, typeContext)
 {
     DebugUtils.CheckNoExternalCallers();
     Debug.Assert(serializationInfo != null, "serializationInfo != null");
     this.serializationInfo = serializationInfo;
 }
Пример #2
0
        /// <summary>
        /// Gets an entity metadata builder for the given entry.
        /// </summary>
        /// <param name="entryState">Entry state to use as reference for information needed by the builder.</param>
        /// <returns>An entity metadata builder.</returns>
        public ODataEntityMetadataBuilder GetEntityMetadataBuilderForReader(IODataJsonLightReaderEntryState entryState)
        {
            Debug.Assert(entryState != null, "entry != null");

            // Only apply the conventional template builder on response. On a request we would only report what's on the wire.
            if (entryState.MetadataBuilder == null)
            {
                ODataEntry entry = entryState.Entry;
                if (this.isResponse)
                {
                    ODataTypeAnnotation typeAnnotation = entry.GetAnnotation <ODataTypeAnnotation>();

                    Debug.Assert(typeAnnotation != null, "The JSON light reader should have already set the ODataTypeAnnotation.");
                    IEdmNavigationSource navigationSource = typeAnnotation.NavigationSource;

                    IEdmEntityType navigationSourceElementType         = this.edmTypeResolver.GetElementType(navigationSource);
                    IODataFeedAndEntryTypeContext typeContext          = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/ null, navigationSource, navigationSourceElementType, entryState.EntityType, this.model, /*throwIfMissingTypeInfo*/ true);
                    IODataEntryMetadataContext    entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, /*serializationInfo*/ null, (IEdmEntityType)entry.GetEdmType().Definition, this, entryState.SelectedProperties);

                    UrlConvention urlConvention            = UrlConvention.ForUserSettingAndTypeContext(/*keyAsSegment*/ null, typeContext);
                    ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(this.ServiceBaseUri, urlConvention);

                    entryState.MetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, this, uriBuilder);
                }
                else
                {
                    entryState.MetadataBuilder = new NoOpEntityMetadataBuilder(entry);
                }
            }

            return(entryState.MetadataBuilder);
        }
Пример #3
0
        /// <summary>
        /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
        /// metadata properties (like EditLink) of the entry may return a value computed by convention,
        /// depending on the metadata level and whether the user manually set an edit link or not.
        /// </summary>
        /// <param name="entry">The entry to create the metadata builder for.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
        /// <param name="serializationInfo">The serialization info for the entry.</param>
        /// <param name="actualEntityType">The entity type of the entry.</param>
        /// <param name="selectedProperties">The selected properties of this scope.</param>
        /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
        /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
        /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
        /// <param name="odataUri">The OData Uri.</param>
        /// <returns>The created metadata builder.</returns>
        internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
            ODataEntry entry,
            IODataFeedAndEntryTypeContext typeContext,
            ODataFeedAndEntrySerializationInfo serializationInfo,
            IEdmEntityType actualEntityType,
            SelectedPropertiesNode selectedProperties,
            bool isResponse,
            bool?keyAsSegment,
            ODataUri odataUri)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(typeContext != null, "typeContext != null");
            Debug.Assert(selectedProperties != null, "selectedProperties != null");

            IODataMetadataContext metadataContext = new ODataMetadataContext(
                isResponse,
                this.model,
                this.NonNullMetadataDocumentUri,
                odataUri);

            UrlConvention urlConvention            = UrlConvention.ForUserSettingAndTypeContext(keyAsSegment, typeContext);
            ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri, urlConvention);

            IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, actualEntityType, metadataContext, selectedProperties);

            return(new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, uriBuilder));
        }
        /// <summary>
        /// Constructs an instance of <see cref="ODataEntryMetadataContext"/>.
        /// </summary>
        /// <param name="entry">The entry instance.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
        protected ODataEntryMetadataContext(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(typeContext != null, "typeContext != null");

            this.entry = entry;
            this.typeContext = typeContext;
        }
        /// <summary>
        /// Constructs an instance of <see cref="ODataEntryMetadataContext"/>.
        /// </summary>
        /// <param name="entry">The entry instance.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
        protected ODataEntryMetadataContext(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(typeContext != null, "typeContext != null");

            this.entry       = entry;
            this.typeContext = typeContext;
        }
Пример #6
0
 /// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention,
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <returns>The created metadata builder.</returns>
 internal abstract ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry,
     IODataFeedAndEntryTypeContext typeContext,
     ODataFeedAndEntrySerializationInfo serializationInfo,
     IEdmEntityType actualEntityType,
     SelectedPropertiesNode selectedProperties,
     bool isResponse,
     bool?keyAsSegment);
Пример #7
0
        /// <summary>
        /// Constructs an instance of <see cref="ODataEntryMetadataContext"/>.
        /// </summary>
        /// <param name="entry">The entry instance.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
        protected ODataEntryMetadataContext(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(typeContext != null, "typeContext != null");

            this.entry       = entry;
            this.typeContext = typeContext;
        }
            /// <summary>
            /// Constructs an instance of <see cref="ODataEntryMetadataContextWithModel"/>.
            /// </summary>
            /// <param name="entry">The entry instance.</param>
            /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
            /// <param name="actualEntityType">The entity type of the entry.</param>
            /// <param name="metadataContext">The metadata context to use.</param>
            /// <param name="selectedProperties">The selected properties.</param>
            internal ODataEntryMetadataContextWithModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, IEdmEntityType actualEntityType, IODataMetadataContext metadataContext, SelectedPropertiesNode selectedProperties)
                : base(entry, typeContext)
            {
                Debug.Assert(actualEntityType != null, "actualEntityType != null");
                Debug.Assert(metadataContext != null, "metadataContext != null");
                Debug.Assert(selectedProperties != null, "selectedProperties != null");

                this.actualEntityType   = actualEntityType;
                this.metadataContext    = metadataContext;
                this.selectedProperties = selectedProperties;
            }
Пример #9
0
 /// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention, 
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <param name="odataUri">The OData Uri.</param>
 /// <returns>The created metadata builder.</returns>
 internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry, 
     IODataFeedAndEntryTypeContext typeContext, 
     ODataFeedAndEntrySerializationInfo serializationInfo, 
     IEdmEntityType actualEntityType, 
     SelectedPropertiesNode selectedProperties, 
     bool isResponse, 
     bool? keyAsSegment,
     ODataUri odataUri)
 {
     return ODataEntityMetadataBuilder.Null;
 }
Пример #10
0
 /// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention,
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <param name="odataUri">The OData Uri.</param>
 /// <returns>The created metadata builder.</returns>
 internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry,
     IODataFeedAndEntryTypeContext typeContext,
     ODataFeedAndEntrySerializationInfo serializationInfo,
     IEdmEntityType actualEntityType,
     SelectedPropertiesNode selectedProperties,
     bool isResponse,
     bool?keyAsSegment,
     ODataUri odataUri)
 {
     return(ODataEntityMetadataBuilder.Null);
 }
Пример #11
0
 /// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention,
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <param name="odataUri">The OData Uri.</param>
 /// <returns>The created metadata builder.</returns>
 internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry,
     IODataFeedAndEntryTypeContext typeContext,
     ODataFeedAndEntrySerializationInfo serializationInfo,
     IEdmEntityType actualEntityType,
     SelectedPropertiesNode selectedProperties,
     bool isResponse,
     bool?keyAsSegment,
     ODataUri odataUri)
 {
     // For minimal metadata we don't want to change the metadata builder that's currently on the entry because the entry might come from a JSON light
     // reader and it would contain the metadata builder from the reader.  Until we give the user the ability to choose whether to write what was reported
     // by the reader versus what was on the wire, we no-op here so the writer will just write what's on the OM for now.
     return(null);
 }
        /// <summary>
        /// Creates an instance of <see cref="ODataEntryMetadataContext"/>.
        /// </summary>
        /// <param name="entry">The entry instance.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
        /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param>
        /// <param name="actualEntityType">The entity type of the entry.</param>
        /// <param name="metadataContext">The metadata context to use.</param>
        /// <param name="selectedProperties">The selected properties.</param>
        /// <returns>A new instance of <see cref="ODataEntryMetadataContext"/>.</returns>
        internal static ODataEntryMetadataContext Create(
            ODataEntry entry,
            IODataFeedAndEntryTypeContext typeContext,
            ODataFeedAndEntrySerializationInfo serializationInfo,
            IEdmEntityType actualEntityType,
            IODataMetadataContext metadataContext,
            SelectedPropertiesNode selectedProperties)
        {
            if (serializationInfo != null)
            {
                return(new ODataEntryMetadataContextWithoutModel(entry, typeContext, serializationInfo));
            }

            return(new ODataEntryMetadataContextWithModel(entry, typeContext, actualEntityType, metadataContext, selectedProperties));
        }
Пример #13
0
 /// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention, 
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in separate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <param name="odataUri">The OData Uri.</param>
 /// <returns>The created metadata builder.</returns>
 internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry, 
     IODataFeedAndEntryTypeContext typeContext, 
     ODataFeedAndEntrySerializationInfo serializationInfo, 
     IEdmEntityType actualEntityType, 
     SelectedPropertiesNode selectedProperties, 
     bool isResponse, 
     bool? keyAsSegment,
     ODataUri odataUri)
 {
     // For minimal metadata we don't want to change the metadata builder that's currently on the entry because the entry might come from a JSON light
     // reader and it would contain the metadata builder from the reader.  Until we give the user the ability to choose whether to write what was reported
     // by the reader versus what was on the wire, we no-op here so the writer will just write what's on the OM for now.
     return null;
 }
Пример #14
0
        /// <summary>
        /// Compute id for containment scenario.
        /// </summary>
        /// <returns>
        /// The <see cref="Uri"/> of @odata.id.
        /// </returns>
        private Uri ComputeIdForContainment()
        {
            Uri uri;

            // check if has parent
            ODataConventionalEntityMetadataBuilder parent = this.ParentMetadataBuilder as ODataConventionalEntityMetadataBuilder;

            if (parent != null)
            {
                // $expand scenario.  Get the parent id
                uri = parent.GetId();

                // And append cast (if needed).
                // A cast segment if the navigation property is defined on a type derived from the entity
                // type declared for the entity set
                IODataFeedAndEntryTypeContext typeContext = parent.entryMetadataContext.TypeContext;
                if (typeContext.NavigationSourceEntityTypeName != typeContext.ExpectedEntityTypeName)
                {
                    // Do not append type cast if we know that the navigation property is in base type, not in derived type.
                    ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel typeContextWithModel = typeContext as ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel;
                    if (typeContextWithModel == null || typeContextWithModel.NavigationSourceEntityType.FindProperty(this.entryMetadataContext.TypeContext.NavigationSourceName) == null)
                    {
                        uri = new Uri(Core.UriUtils.EnsureTaillingSlash(uri), parent.entryMetadataContext.ActualEntityTypeName);
                    }
                }
            }
            else
            {
                // direct access scenario.
                uri = this.uriBuilder.BuildBaseUri();
                ODataUri odataUri = this.ODataUri ?? this.metadataContext.ODataUri;
                uri = this.GetContainingEntitySetUri(uri, odataUri);
            }

            // A path segment for the containment navigation property
            uri = this.uriBuilder.BuildEntitySetUri(uri, this.entryMetadataContext.TypeContext.NavigationSourceName);

            if (this.entryMetadataContext.TypeContext.IsFromCollection)
            {
                uri = this.uriBuilder.BuildEntityInstanceUri(
                    uri,
                    this.ComputedKeyProperties,
                    this.entryMetadataContext.ActualEntityTypeName);
            }

            return(uri);
        }
Пример #15
0
        /// <summary>
        /// Gets the url convention for the given user setting and type context.
        /// </summary>
        /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
        /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
        /// <param name="typeContext">The type context for the entry or feed being written.</param>
        /// <returns>The convention to use when generating URLs.</returns>
        internal static UrlConvention ForUserSettingAndTypeContext(bool?keyAsSegment, IODataFeedAndEntryTypeContext typeContext)
        {
            Debug.Assert(typeContext != null, "typeContext != null");

            // The setting from the user is an override, so check if it was set.
            if (keyAsSegment.HasValue)
            {
                return(CreateWithExplicitValue(keyAsSegment.Value));
            }

            return(typeContext.UrlConvention);
        }
Пример #16
0
        /// <summary>
        /// Gets the url convention for the given user setting and type context.
        /// </summary>
        /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
        /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
        /// <param name="typeContext">The type context for the entry or feed being written.</param>
        /// <returns>The convention to use when generating URLs.</returns>
        internal static UrlConvention ForUserSettingAndTypeContext(bool? keyAsSegment, IODataFeedAndEntryTypeContext typeContext)
        {
            Debug.Assert(typeContext != null, "typeContext != null");

            // The setting from the user is an override, so check if it was set.
            if (keyAsSegment.HasValue)
            {
                return CreateWithExplicitValue(keyAsSegment.Value);
            }

            return typeContext.UrlConvention;
        }
            /// <summary>
            /// Constructs an instance of <see cref="ODataEntryMetadataContextWithModel"/>.
            /// </summary>
            /// <param name="entry">The entry instance.</param>
            /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
            /// <param name="actualEntityType">The entity type of the entry.</param>
            /// <param name="metadataContext">The metadata context to use.</param>
            /// <param name="selectedProperties">The selected properties.</param>
            internal ODataEntryMetadataContextWithModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, IEdmEntityType actualEntityType, IODataMetadataContext metadataContext, SelectedPropertiesNode selectedProperties)
                : base(entry, typeContext)
            {
                Debug.Assert(actualEntityType != null, "actualEntityType != null");
                Debug.Assert(metadataContext != null, "metadataContext != null");
                Debug.Assert(selectedProperties != null, "selectedProperties != null");

                this.actualEntityType = actualEntityType;
                this.metadataContext = metadataContext;
                this.selectedProperties = selectedProperties;
            }
 /// <summary>
 /// Constructs an instance of <see cref="ODataEntryMetadataContextWithoutModel"/>.
 /// </summary>
 /// <param name="entry">The entry instance.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
 /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param>
 internal ODataEntryMetadataContextWithoutModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo)
     : base(entry, typeContext)
 {
     Debug.Assert(serializationInfo != null, "serializationInfo != null");
     this.serializationInfo = serializationInfo;
 }
        /// <summary>
        /// Creates an instance of <see cref="ODataEntryMetadataContext"/>.
        /// </summary>
        /// <param name="entry">The entry instance.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
        /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param>
        /// <param name="actualEntityType">The entity type of the entry.</param>
        /// <param name="metadataContext">The metadata context to use.</param>
        /// <param name="selectedProperties">The selected properties.</param>
        /// <returns>A new instance of <see cref="ODataEntryMetadataContext"/>.</returns>
        internal static ODataEntryMetadataContext Create(
            ODataEntry entry,
            IODataFeedAndEntryTypeContext typeContext,
            ODataFeedAndEntrySerializationInfo serializationInfo,
            IEdmEntityType actualEntityType,
            IODataMetadataContext metadataContext,
            SelectedPropertiesNode selectedProperties)
        {
            if (serializationInfo != null)
            {
                return new ODataEntryMetadataContextWithoutModel(entry, typeContext, serializationInfo);
            }

            return new ODataEntryMetadataContextWithModel(entry, typeContext, actualEntityType, metadataContext, selectedProperties);
        }
Пример #20
0
        /// <summary>
        /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
        /// metadata properties (like EditLink) of the entry may return a value computed by convention, 
        /// depending on the metadata level and whether the user manually set an edit link or not.
        /// </summary>
        /// <param name="entry">The entry to create the metadata builder for.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
        /// <param name="serializationInfo">The serialization info for the entry.</param>
        /// <param name="actualEntityType">The entity type of the entry.</param>
        /// <param name="selectedProperties">The selected properties of this scope.</param>
        /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
        /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
        /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
        /// <param name="odataUri">The OData Uri.</param>
        /// <returns>The created metadata builder.</returns>
        internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
            ODataEntry entry, 
            IODataFeedAndEntryTypeContext typeContext, 
            ODataFeedAndEntrySerializationInfo serializationInfo, 
            IEdmEntityType actualEntityType, 
            SelectedPropertiesNode selectedProperties, 
            bool isResponse, 
            bool? keyAsSegment,
            ODataUri odataUri)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(typeContext != null, "typeContext != null");
            Debug.Assert(selectedProperties != null, "selectedProperties != null");

            IODataMetadataContext metadataContext = new ODataMetadataContext(
                isResponse,
                this.model,
                this.NonNullMetadataDocumentUri,
                odataUri);
            
            UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(keyAsSegment, typeContext);
            ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri, urlConvention);

            IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, actualEntityType, metadataContext, selectedProperties);
            return new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, uriBuilder);
        }