Ejemplo n.º 1
0
        /// <summary>
        /// Generates a string to be used as the skip token value within the next link.
        /// </summary>
        /// <param name="lastMember"> Object based on which SkipToken value will be generated.</param>
        /// <param name="model">The edm model.</param>
        /// <param name="orderByNodes">List of orderByNodes used to generate the skiptoken value.</param>
        /// <returns>Value for the skiptoken to be used in the next link.</returns>
        private static string GenerateSkipTokenValue(Object lastMember, IEdmModel model, IList <OrderByNode> orderByNodes)
        {
            if (lastMember == null)
            {
                return(String.Empty);
            }

            IEnumerable <IEdmProperty> propertiesForSkipToken = GetPropertiesForSkipToken(lastMember, model, orderByNodes);
            StringBuilder skipTokenBuilder = new StringBuilder(String.Empty);

            if (propertiesForSkipToken == null)
            {
                return(skipTokenBuilder.ToString());
            }

            int    count = 0;
            string uriLiteral;
            object value;
            int    lastIndex         = propertiesForSkipToken.Count() - 1;
            IEdmStructuredObject obj = lastMember as IEdmStructuredObject;

            foreach (IEdmProperty edmProperty in propertiesForSkipToken)
            {
                bool   islast          = count == lastIndex;
                string clrPropertyName = EdmLibHelpers.GetClrPropertyName(edmProperty, model);
                if (obj != null)
                {
                    obj.TryGetPropertyValue(clrPropertyName, out value);
                }
                else
                {
                    value = lastMember.GetType().GetProperty(clrPropertyName).GetValue(lastMember);
                }

                if (value == null)
                {
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V401);
                }
                else if (edmProperty.Type.IsEnum())
                {
                    ODataEnumValue enumValue = new ODataEnumValue(value.ToString(), value.GetType().FullName);
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(enumValue, ODataVersion.V401, model);
                }
                else if (edmProperty.Type.IsDateTimeOffset() && value is DateTime)
                {
                    var dateTime            = (DateTime)value;
                    var dateTimeOffsetValue = TimeZoneInfoHelper.ConvertToDateTimeOffset(dateTime);
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(dateTimeOffsetValue, ODataVersion.V401, model);
                }
                else
                {
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V401, model);
                }

                skipTokenBuilder.Append(edmProperty.Name).Append(propertyDelimiter).Append(uriLiteral).Append(islast ? String.Empty : CommaDelimiter.ToString());
                count++;
            }

            return(skipTokenBuilder.ToString());
        }
Ejemplo n.º 2
0
 private IEdmStructuredObject EnsureModel(IEdmStructuredObject obj)
 {
     if (obj != null)
     {
         obj.SetModel(this.EdmModel);
     }
     return(obj);
 }
Ejemplo n.º 3
0
        internal IEdmTypeReference GetEdmType(object instance, Type type)
        {
            IEdmTypeReference edmType;

            IEdmObject edmObject = instance as IEdmObject;

            if (edmObject != null)
            {
                IEdmStructuredObject edmStructuredObject = edmObject as IEdmStructuredObject;
                if (edmStructuredObject != null)
                {
                    edmStructuredObject.SetModel(Model);
                }

                edmType = edmObject.GetEdmType();
                if (edmType == null)
                {
                    throw Error.InvalidOperation(SRResources.EdmTypeCannotBeNull, edmObject.GetType().FullName,
                                                 typeof(IEdmObject).Name);
                }
            }
            else
            {
                if (Model == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                }

                _typeMappingCache = _typeMappingCache ?? Model.GetTypeMappingCache();
                edmType           = _typeMappingCache.GetEdmType(type, Model);

                if (edmType == null)
                {
                    if (instance != null)
                    {
                        edmType = _typeMappingCache.GetEdmType(instance.GetType(), Model);
                    }

                    if (edmType == null)
                    {
                        throw Error.InvalidOperation(SRResources.ClrTypeNotInModel, type);
                    }
                }
                else if (instance != null)
                {
                    IEdmTypeReference actualType = _typeMappingCache.GetEdmType(instance.GetType(), Model);
                    if (actualType != null && actualType != edmType)
                    {
                        edmType = actualType;
                    }
                }
            }

            return(edmType);
        }
        private EntityInstanceContext(ODataSerializerContext serializerContext, IEdmEntityTypeReference entityType, IEdmStructuredObject edmObject)
        {
            if (serializerContext == null)
            {
                throw Error.ArgumentNull("serializerContext");
            }

            SerializerContext = serializerContext;
            EntityType = entityType.EntityDefinition();
            EdmObject = edmObject;
        }
Ejemplo n.º 5
0
        private ResourceContext(ODataSerializerContext serializerContext, IEdmStructuredTypeReference structuredType, IEdmStructuredObject edmObject)
        {
            if (serializerContext == null)
            {
                throw Error.ArgumentNull("serializerContext");
            }

            SerializerContext = serializerContext;
            StructuredType    = structuredType.StructuredDefinition();
            EdmObject         = edmObject;
        }
Ejemplo n.º 6
0
        private ODataSerializer GetSerializer(Type type, object value, ODataSerializerProvider serializerProvider)
        {
            ODataSerializer serializer;

            IEdmObject edmObject = value as IEdmObject;

            if (edmObject != null)
            {
                IEdmStructuredObject edmStructuredObject = edmObject as IEdmStructuredObject;
                if (edmStructuredObject != null)
                {
                    edmStructuredObject.SetModel(Request.GetModel());
                }

                IEdmTypeReference edmType = edmObject.GetEdmType();
                if (edmType == null)
                {
                    throw new SerializationException(Error.Format(SRResources.EdmTypeCannotBeNull,
                                                                  edmObject.GetType().FullName, typeof(IEdmObject).Name));
                }

                serializer = serializerProvider.GetEdmTypeSerializer(edmType);
                if (serializer == null)
                {
                    string message = Error.Format(SRResources.TypeCannotBeSerialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter).Name);
                    throw new SerializationException(message);
                }
            }
            else
            {
                var applyClause = Request.ODataProperties().ApplyClause;
                // get the most appropriate serializer given that we support inheritance.
                if (applyClause == null)
                {
                    type = value == null ? type : value.GetType();
                }

                serializer = serializerProvider.GetODataPayloadSerializer(type, Request);
                if (serializer == null)
                {
                    string message = Error.Format(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                    throw new SerializationException(message);
                }
            }

            return(serializer);
        }
Ejemplo n.º 7
0
        /// <summary>
        ///     Convert EdmStructuredObject to an object with type.
        /// </summary>
        /// <param name="edmStructuredObject">An object with EdmStructuredType.</param>
        /// <param name="type">Desired object type.</param>
        /// <returns>Result object.</returns>
        private static object ConvertEdmStructuredObjectToTypedObject(
            IEdmStructuredObject edmStructuredObject, Type type)
        {
            if (edmStructuredObject == null)
            {
                return(null);
            }

            var obj           = Activator.CreateInstance(type);
            var propertyInfos = type.GetProperties();

            foreach (var propertyInfo in propertyInfos)
            {
                if (!propertyInfo.CanWrite)
                {
                    continue;
                }

                object value = null;
                edmStructuredObject.TryGetPropertyValue(propertyInfo.Name, out value);
                if (value == null)
                {
                    propertyInfo.SetValue(obj, value);
                    continue;
                }

                if (!propertyInfo.PropertyType.IsInstanceOfType(value))
                {
                    var edmObj = value as IEdmStructuredObject;
                    if (edmObj == null)
                    {
                        throw new NotSupportedException(string.Format(
                                                            CultureInfo.InvariantCulture,
                                                            propertyInfo.PropertyType.ToString()));
                    }

                    value = ConvertEdmStructuredObjectToTypedObject(edmObj, propertyInfo.PropertyType);
                }

                propertyInfo.SetValue(obj, value);
            }

            return(obj);
        }
Ejemplo n.º 8
0
        private static IEdmStructuredObject AsEdmResourceObject(object resourceInstance, IEdmStructuredTypeReference structuredType, IEdmModel model)
        {
            if (structuredType == null)
            {
                throw Error.ArgumentNull("structuredType");
            }

            IEdmStructuredObject edmStructuredObject = resourceInstance as IEdmStructuredObject;

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

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

            Contract.Assert(structuredType.IsComplex());
            return(new TypedEdmComplexObject(resourceInstance, structuredType.AsComplex(), model));
        }
Ejemplo n.º 9
0
        public static string GetEntityKeyValue(EntityInstanceContext entityContext)
        {
            Contract.Assert(entityContext != null);
            Contract.Assert(entityContext.EntityType != null);
            Contract.Assert(entityContext.EdmObject != null);

            IEnumerable <IEdmProperty> keys           = entityContext.EntityType.Key();
            IEdmStructuredObject       entityInstance = entityContext.EdmObject;

            // TODO: BUG 453795: reflection cleanup
            if (keys.Count() == 1)
            {
                return(GetUriRepresentationForKeyValue(keys.First(), entityContext));
            }
            else
            {
                IEnumerable <string> keyValues =
                    keys.Select(key => String.Format(
                                    CultureInfo.InvariantCulture, "{0}={1}", key.Name, GetUriRepresentationForKeyValue(key, entityContext)));
                return(String.Join(",", keyValues));
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Gets the property value and wraps it in a DTO wrapper if necessary.
        /// </summary>
        public static bool TryGetPropertyValue <T>(this IEdmStructuredObject targetObject, string propertyName, out T value)
        {
            object internalValue;

            if (targetObject.TryGetPropertyValue(propertyName, out internalValue))
            {
                // wrap by dto wrapper, if applicable
                object wrappedValue;
                if (PropertyValueWrappingHelper.TryWrapEdmObject(internalValue, out wrappedValue))
                {
                    internalValue = wrappedValue;
                }

                // now cast to desired type
                if (internalValue is T)
                {
                    value = (T)internalValue;
                    return(true);
                }
            }

            value = default(T);
            return(false);
        }
Ejemplo n.º 11
0
        internal List <ODataProperty> AppendDynamicProperties(object source, IEdmStructuredTypeReference structuredType,
                                                              ODataSerializerContext writeContext, List <ODataProperty> declaredProperties,
                                                              string[] selectedDynamicProperties)
        {
            Contract.Assert(source != null);
            Contract.Assert(structuredType != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(writeContext.Model != null);

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

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

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

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

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

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

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

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

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

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

            return(dynamicProperties);
        }
        /// <summary>
        /// Appends the dynamic properties of primitive, enum or the collection of them into the given <see cref="ODataResource"/>.
        /// If the dynamic property is a property of the complex or collection of complex, it will be saved into
        /// the dynamic complex properties dictionary of <paramref name="resourceContext"/> and be written later.
        /// </summary>
        /// <param name="resource">The <see cref="ODataResource"/> describing the resource.</param>
        /// <param name="selectExpandNode">The <see cref="SelectExpandNode"/> describing the response graph.</param>
        /// <param name="resourceContext">The context for the resource instance being written.</param>
        public override void AppendDynamicProperties(ODataResource resource, SelectExpandNode selectExpandNode,
                                                     ResourceContext resourceContext)
        {
            if (!resourceContext.StructuredType.IsOpen || // non-open type
                (!selectExpandNode.SelectAllDynamicProperties && selectExpandNode.SelectedDynamicProperties == null))
            {
                return;
            }

            bool nullDynamicPropertyEnabled = true; // false

            if (resourceContext.EdmObject is EdmDeltaComplexObject || resourceContext.EdmObject is EdmDeltaEntityObject)
            {
                nullDynamicPropertyEnabled = true;
            }

            IEdmStructuredType   structuredType   = resourceContext.StructuredType;
            IEdmStructuredObject structuredObject = resourceContext.EdmObject;
            object value;
            IDelta delta = structuredObject as IDelta;

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

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

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

            // To test SelectedDynamicProperties == null is enough to filter the dynamic properties.
            // Because if SelectAllDynamicProperties == true, SelectedDynamicProperties should be null always.
            // So `selectExpandNode.SelectedDynamicProperties == null` covers `SelectAllDynamicProperties == true` scenario.
            // If `selectExpandNode.SelectedDynamicProperties != null`, then we should test whether the property is selected or not using "Contains(...)".
            IEnumerable <KeyValuePair <string, object> > dynamicPropertiesToSelect =
                dynamicPropertyDictionary.Where(x => selectExpandNode.SelectedDynamicProperties == null || selectExpandNode.SelectedDynamicProperties.Contains(x.Key));

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

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

                    continue;
                }

                //if (declaredPropertyNameSet.Contains(dynamicProperty.Key))
                //{
                //continue;
                //}

                IEdmTypeReference edmTypeReference = GetEdmType(dynamicProperty.Value,
                                                                dynamicProperty.Value.GetType());
                //for non navigational properties it will be null
                if (edmTypeReference == null)
                {
                    dynamicProperties.Add(new ODataProperty
                    {
                        Name  = dynamicProperty.Key,
                        Value = new ODataUntypedValue
                        {
                            RawValue = JsonConvert.SerializeObject(dynamicProperty.Value, new JsonSerializerSettings
                            {
                                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                                TypeNameHandling      = TypeNameHandling.None
                            }),
                            TypeAnnotation = new ODataTypeAnnotation(typeof(string).Name)
                        },
                    });
                }

                else if (edmTypeReference != null)
                {
                    if (edmTypeReference.IsStructured() ||
                        (edmTypeReference.IsCollection() && edmTypeReference.AsCollection().ElementType().IsStructured()))
                    {
                        if (resourceContext.DynamicComplexProperties == null)
                        {
                            resourceContext.DynamicComplexProperties = new ConcurrentDictionary <string, object>();
                        }

                        resourceContext.DynamicComplexProperties.Add(dynamicProperty);
                    }
                    else
                    {
                        ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference);
                        if (propertySerializer == null)
                        {
                            throw new InvalidOperationException($"Required serilizer for type {edmTypeReference.FullName()} not found");
                        }

                        dynamicProperties.Add(CreateProperty(
                                                  dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, resourceContext.SerializerContext));
                    }
                }
            }

            if (dynamicProperties.Any())
            {
                resource.Properties = resource.Properties.Concat(dynamicProperties);
            }
        }
Ejemplo n.º 13
0
        public virtual void AppendDynamicProperties(ODataResource resource, SelectExpandNode selectExpandNode,
                                                    ResourceContext resourceContext)
        {
            Contract.Assert(resource != null);
            Contract.Assert(selectExpandNode != null);
            Contract.Assert(resourceContext != null);

            if (!resourceContext.StructuredType.IsOpen || // non-open type
                (!selectExpandNode.SelectAllDynamicProperties && !selectExpandNode.SelectedDynamicProperties.Any()))
            {
                return;
            }

            bool nullDynamicPropertyEnabled = false;

            if (resourceContext.Request != null)
            {
                // TODO:

                /*
                 * HttpConfiguration configuration = resourceContext.Request.GetConfiguration();
                 * if (configuration != null)
                 * {
                 *  nullDynamicPropertyEnabled = configuration.HasEnabledNullDynamicProperty();
                 * }*/
            }

            IEdmStructuredType   structuredType   = resourceContext.StructuredType;
            IEdmStructuredObject structuredObject = resourceContext.EdmObject;
            object value;
            IDelta delta = structuredObject as IDelta;

            if (delta == null)
            {
                PropertyInfo dynamicPropertyInfo = EdmLibHelpers.GetDynamicPropertyDictionary(structuredType,
                                                                                              resourceContext.EdmModel);
                if (dynamicPropertyInfo == null || structuredObject == null ||
                    !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null)
                {
                    return;
                }
            }
            else
            {
                value = ((EdmStructuredObject)structuredObject).TryGetDynamicProperties();
            }

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

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

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

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

                    continue;
                }

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

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

                if (edmTypeReference.IsStructured() ||
                    (edmTypeReference.IsCollection() && edmTypeReference.AsCollection().ElementType().IsStructured()))
                {
                    if (resourceContext.DynamicComplexProperties == null)
                    {
                        resourceContext.DynamicComplexProperties = new ConcurrentDictionary <string, object>();
                    }

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

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

            if (dynamicProperties.Any())
            {
                resource.Properties = resource.Properties.Concat(dynamicProperties);
            }
        }
Ejemplo n.º 14
0
        internal static void WriteToStream(
            Type type,
            object value,
            IEdmModel model,
            ODataVersion version,
            Uri baseAddress,
            MediaTypeHeaderValue contentType,
            IWebApiUrlHelper internaUrlHelper,
            IWebApiRequestMessage internalRequest,
            IWebApiHeaders internalRequestHeaders,
            Func <IServiceProvider, ODataMessageWrapper> getODataMessageWrapper,
            Func <IEdmTypeReference, ODataSerializer> getEdmTypeSerializer,
            Func <Type, ODataSerializer> getODataPayloadSerializer,
            Func <ODataSerializerContext> getODataSerializerContext)
        {
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            IEdmStructuredObject edmStructuredObject = value as IEdmStructuredObject;

            if (edmStructuredObject != null)
            {
                edmStructuredObject.SetModel(model);
            }

            ODataSerializer serializer = GetSerializer(type, value, internalRequest, getEdmTypeSerializer, getODataPayloadSerializer);

            ODataPath            path = internalRequest.Context.Path;
            IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource;

            // serialize a response
            IODataResponseMessage responseMessage = PrepareResponseMessage(internalRequest, internalRequestHeaders, getODataMessageWrapper);

            ODataMessageWriterSettings writerSettings = internalRequest.WriterSettings;

            writerSettings.BaseUri     = baseAddress;
            writerSettings.Version     = version;
            writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

            string metadataLink = internaUrlHelper.CreateODataLink(MetadataSegment.Instance);

            if (metadataLink == null)
            {
                throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
            }

            //Set this variable if the SelectExpandClause is different from the processed clause on the Query options
            SelectExpandClause selectExpandDifferentFromQueryOptions = null;

            if (internalRequest.Context.QueryOptions != null && internalRequest.Context.QueryOptions.SelectExpand != null)
            {
                if (internalRequest.Context.QueryOptions.SelectExpand.ProcessedSelectExpandClause != internalRequest.Context.ProcessedSelectExpandClause)
                {
                    selectExpandDifferentFromQueryOptions = internalRequest.Context.ProcessedSelectExpandClause;
                }
            }
            else if (internalRequest.Context.ProcessedSelectExpandClause != null)
            {
                selectExpandDifferentFromQueryOptions = internalRequest.Context.ProcessedSelectExpandClause;
            }

            writerSettings.ODataUri = new ODataUri
            {
                ServiceRoot = baseAddress,

                // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath.
                SelectAndExpand = internalRequest.Context.ProcessedSelectExpandClause,
                Apply           = internalRequest.Context.ApplyClause,
                Path            = (path == null || IsOperationPath(path)) ? null : path.Path,
            };

            ODataMetadataLevel metadataLevel = ODataMetadataLevel.MinimalMetadata;

            if (contentType != null)
            {
                IEnumerable <KeyValuePair <string, string> > parameters =
                    contentType.Parameters.Select(val => new KeyValuePair <string, string>(val.Name, val.Value));
                metadataLevel = ODataMediaTypes.GetMetadataLevel(contentType.MediaType, parameters);
            }

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = getODataSerializerContext();
                writeContext.NavigationSource = targetNavigationSource;
                writeContext.Model            = model;
                writeContext.RootElementName  = GetRootElementName(path) ?? "root";
                writeContext.SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.ResourceSet;
                writeContext.Path          = path;
                writeContext.MetadataLevel = metadataLevel;
                writeContext.QueryOptions  = internalRequest.Context.QueryOptions;

                //Set the SelectExpandClause on the context if it was explicitly specified.
                if (selectExpandDifferentFromQueryOptions != null)
                {
                    writeContext.SelectExpandClause = selectExpandDifferentFromQueryOptions;
                }

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }