/// <summary>
        /// Calculates the version based on the ODataUri provided
        /// </summary>
        /// <param name="request">Request to calculate from</param>
        /// <param name="maxProtocolVersion">Max Protocol version of the server</param>
        /// <returns>Data Service Protocol Version</returns>
        public DataServiceProtocolVersion CalculateMinRequestVersion(ODataRequest request, DataServiceProtocolVersion maxProtocolVersion)
        {
            ExceptionUtilities.CheckArgumentNotNull(request, "request");
            ExceptionUtilities.Assert(maxProtocolVersion != DataServiceProtocolVersion.Unspecified, "Max protocol version cannot be unspecified when calculating the MinVersion");

            string contentType = request.GetHeaderValueIfExists(HttpHeaders.ContentType);
            DataServiceProtocolVersion dataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.DataServiceVersion));
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));
            HttpVerb effectiveVerb = request.GetEffectiveVerb();

            if (contentType == null)
            {
                contentType = MimeTypes.Any;
            }

            // No real request payload for Delete so its automatically version 1
            if (request.GetEffectiveVerb() == HttpVerb.Delete)
            {
                return DataServiceProtocolVersion.V4;
            }

            if (effectiveVerb.IsUpdateVerb() || effectiveVerb == HttpVerb.Post)
            {
                EntitySet entitySet = null;
                if (request.Uri.TryGetExpectedEntitySet(out entitySet))
                {
                    // Determine if the operation and Uri combined yields something that we need to look at the metadata to determine the version or not
                    bool processTypeMetadata = false;

                    // Typically for all posts there is some type of payload so we should analyze the metadata
                    if (effectiveVerb == HttpVerb.Post)
                    {
                        processTypeMetadata = true;
                    }
                    else if (dataServiceVersion != DataServiceProtocolVersion.Unspecified && request.PreferHeaderApplies(maxProtocolVersion))
                    {
                        processTypeMetadata = true;
                    }

                    IEnumerable<EntityType> entityTypes = VersionHelper.GetEntityTypes(entitySet);

                    // Whenever there is an update operation and EPM is involved we need to check the metadata version
                    if (entityTypes.SelectMany(et => et.Annotations.OfType<PropertyMappingAnnotation>()).Where(fma => fma.KeepInContent == false).Any())
                    {
                        processTypeMetadata = true;
                    }

                    if (processTypeMetadata)
                    {
                        return VersionHelper.GetMaximumVersion(entityTypes.Select(et => et.CalculateEntityPropertyMappingProtocolVersion(VersionCalculationType.Request, contentType, maxProtocolVersion, maxDataServiceVersion)).ToArray());
                    }
                }

                return DataServiceProtocolVersion.V4;
            }

            return VersionHelper.CalculateUriMinRequestProtocolVersion(request.Uri, contentType, maxProtocolVersion, maxDataServiceVersion);
        }
        private bool TryCalculateODataResponseError(ODataRequest request, DataServiceProtocolVersion dataServiceVersion, DataServiceProtocolVersion maxDataServiceVersion, DataServiceProtocolVersion maxProtocolVersion, out ExpectedErrorMessage expectedErrorMessage)
        {
            expectedErrorMessage = null;

            string preferHeader = request.GetHeaderValueIfExists(HttpHeaders.Prefer);

            if (preferHeader != null &&
                maxProtocolVersion > DataServiceProtocolVersion.V4 &&
                dataServiceVersion > DataServiceProtocolVersion.V4 &&
                maxDataServiceVersion != DataServiceProtocolVersion.Unspecified &&
                maxDataServiceVersion < DataServiceProtocolVersion.V4 &&
                request.Verb != HttpVerb.Delete)
            {
                expectedErrorMessage = new ExpectedErrorMessage(MaxDataServiceVersionTooLow, maxDataServiceVersion.ConvertToHeaderFormat(), DataServiceProtocolVersion.V4.ConvertToIntegerFormat(), "0");
                return(true);
            }

            // Now do payload processing
            DataServiceProtocolVersion expectedResponseVersion = this.MinimumVersionRequiredCalculator.CalculateMinResponseVersion(request, maxProtocolVersion);

            // Now ensure its not greater than than MDSV
            if (maxDataServiceVersion != DataServiceProtocolVersion.Unspecified && expectedResponseVersion > maxDataServiceVersion)
            {
                expectedErrorMessage = new ExpectedErrorMessage(MaxDataServiceVersionTooLow, maxDataServiceVersion.ConvertToHeaderFormat(), expectedResponseVersion.ConvertToIntegerFormat(), "0");
                return(true);
            }

            return(false);
        }
Ejemplo n.º 3
0
        internal static bool TryGetExpectedType(ODataRequest request, out EntityType entityType)
        {
            EntitySet entitySet;

            if (request.Uri.TryGetExpectedEntitySet(out entitySet))
            {
                var possibleTypes = entitySet.Container.Model.EntityTypes.Where(t => t.IsKindOf(entitySet.EntityType)).ToList();
                if (possibleTypes.Count == 1)
                {
                    entityType = possibleTypes[0];
                    return(true);
                }

                string typeName = null;
                if (entitySet.EntityType.HasStream())
                {
                    typeName = request.GetHeaderValueIfExists(HttpHeaders.MediaLinkEntryEntityTypeHint);
                }
                else if (request.Body != null && request.Body.RootElement.ElementType == ODataPayloadElementType.EntityInstance)
                {
                    typeName = ((EntityInstance)request.Body.RootElement).FullTypeName;
                }

                if (typeName != null)
                {
                    entityType = possibleTypes.SingleOrDefault(t => t.FullName == typeName);
                    return(entityType != null);
                }
            }

            entityType = null;
            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Calculates the version based on the ODataUri provided
        /// </summary>
        /// <param name="request">Request to calculate from</param>
        /// <param name="maxProtocolVersion">Max Protocol version of the server</param>
        /// <returns>Data Service Protocol Version</returns>
        public DataServiceProtocolVersion CalculateMinRequestVersion(ODataRequest request, DataServiceProtocolVersion maxProtocolVersion)
        {
            ExceptionUtilities.CheckArgumentNotNull(request, "request");
            ExceptionUtilities.Assert(maxProtocolVersion != DataServiceProtocolVersion.Unspecified, "Max protocol version cannot be unspecified when calculating the MinVersion");

            string contentType = request.GetHeaderValueIfExists(HttpHeaders.ContentType);
            DataServiceProtocolVersion dataServiceVersion    = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.DataServiceVersion));
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));
            HttpVerb effectiveVerb = request.GetEffectiveVerb();

            if (contentType == null)
            {
                contentType = MimeTypes.Any;
            }

            // No real request payload for Delete so its automatically version 1
            if (request.GetEffectiveVerb() == HttpVerb.Delete)
            {
                return(DataServiceProtocolVersion.V4);
            }

            if (effectiveVerb.IsUpdateVerb() || effectiveVerb == HttpVerb.Post)
            {
                EntitySet entitySet = null;
                if (request.Uri.TryGetExpectedEntitySet(out entitySet))
                {
                    // Determine if the operation and Uri combined yields something that we need to look at the metadata to determine the version or not
                    bool processTypeMetadata = false;

                    // Typically for all posts there is some type of payload so we should analyze the metadata
                    if (effectiveVerb == HttpVerb.Post)
                    {
                        processTypeMetadata = true;
                    }
                    else if (dataServiceVersion != DataServiceProtocolVersion.Unspecified && request.PreferHeaderApplies(maxProtocolVersion))
                    {
                        processTypeMetadata = true;
                    }

                    IEnumerable <EntityType> entityTypes = VersionHelper.GetEntityTypes(entitySet);

                    // Whenever there is an update operation and EPM is involved we need to check the metadata version
                    if (entityTypes.SelectMany(et => et.Annotations.OfType <PropertyMappingAnnotation>()).Where(fma => fma.KeepInContent == false).Any())
                    {
                        processTypeMetadata = true;
                    }

                    if (processTypeMetadata)
                    {
                        return(VersionHelper.GetMaximumVersion(entityTypes.Select(et => et.CalculateEntityPropertyMappingProtocolVersion(VersionCalculationType.Request, contentType, maxProtocolVersion, maxDataServiceVersion)).ToArray()));
                    }
                }

                return(DataServiceProtocolVersion.V4);
            }

            return(VersionHelper.CalculateUriMinRequestProtocolVersion(request.Uri, contentType, maxProtocolVersion, maxDataServiceVersion));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Calculates the version based on the ODataUri provided
        /// </summary>
        /// <param name="request">Request to calculate from</param>
        /// <param name="maxProtocolVersion">Max Protocol version of the server</param>
        /// <returns>Data Service Protocol Version</returns>
        public DataServiceProtocolVersion CalculateMinResponseVersion(ODataRequest request, DataServiceProtocolVersion maxProtocolVersion)
        {
            ExceptionUtilities.CheckArgumentNotNull(request, "request");
            ExceptionUtilities.Assert(maxProtocolVersion != DataServiceProtocolVersion.Unspecified, "Max protocol version cannot be unspecified when calculating the MinVersion");

            string contentType = request.GetHeaderValueIfExists(HttpHeaders.Accept);
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));
            HttpVerb effectiveVerb = request.GetEffectiveVerb();

            if (contentType == null)
            {
                contentType = MimeTypes.Any;
            }

            if (effectiveVerb == HttpVerb.Post || effectiveVerb.IsUpdateVerb())
            {
                DataServiceProtocolVersion version = DataServiceProtocolVersion.V4;

                string preferHeaderValue = request.GetHeaderValueIfExists(HttpHeaders.Prefer);

                // Bump to Version 3 if prefer header is specified and its > V3 server
                if (preferHeaderValue != null && request.PreferHeaderApplies(maxProtocolVersion))
                {
                    version = version.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
                }

                // for insert or update, versioning is specific to the type
                EntityType expectedEntityType;
                if (TryGetExpectedType(request, out expectedEntityType))
                {
                    version = VersionHelper.IncreaseVersionIfRequired(version, VersionHelper.CalculateProtocolVersion(expectedEntityType, contentType, VersionCalculationType.Response, maxProtocolVersion, maxDataServiceVersion));
                }

                return(version);
            }

            return(VersionHelper.CalculateUriResponseMinProtocolVersion(request.Uri, contentType, maxProtocolVersion, maxDataServiceVersion));
        }
        /// <summary>
        /// Calculates the version based on the ODataUri provided
        /// </summary>
        /// <param name="request">Request to calculate from</param>
        /// <param name="maxProtocolVersion">Max Protocol version of the server</param>
        /// <returns>Data Service Protocol Version</returns>
        public DataServiceProtocolVersion CalculateMinResponseVersion(ODataRequest request, DataServiceProtocolVersion maxProtocolVersion)
        {
            ExceptionUtilities.CheckArgumentNotNull(request, "request");
            ExceptionUtilities.Assert(maxProtocolVersion != DataServiceProtocolVersion.Unspecified, "Max protocol version cannot be unspecified when calculating the MinVersion");

            string contentType = request.GetHeaderValueIfExists(HttpHeaders.Accept);
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));
            HttpVerb effectiveVerb = request.GetEffectiveVerb();

            if (contentType == null)
            {
                contentType = MimeTypes.Any;
            }

            if (effectiveVerb == HttpVerb.Post || effectiveVerb.IsUpdateVerb())
            {
                DataServiceProtocolVersion version = DataServiceProtocolVersion.V4;

                string preferHeaderValue = request.GetHeaderValueIfExists(HttpHeaders.Prefer);

                // Bump to Version 3 if prefer header is specified and its > V3 server
                if (preferHeaderValue != null && request.PreferHeaderApplies(maxProtocolVersion))
                {
                    version = version.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
                }

                // for insert or update, versioning is specific to the type
                EntityType expectedEntityType;
                if (TryGetExpectedType(request, out expectedEntityType))
                {
                    version = VersionHelper.IncreaseVersionIfRequired(version, VersionHelper.CalculateProtocolVersion(expectedEntityType, contentType, VersionCalculationType.Response, maxProtocolVersion, maxDataServiceVersion));
                }

                return version;
            }

            return VersionHelper.CalculateUriResponseMinProtocolVersion(request.Uri, contentType, maxProtocolVersion, maxDataServiceVersion);
        }
        internal static bool TryGetExpectedType(ODataRequest request, out EntityType entityType)
        {
            EntitySet entitySet;
            if (request.Uri.TryGetExpectedEntitySet(out entitySet))
            {
                var possibleTypes = entitySet.Container.Model.EntityTypes.Where(t => t.IsKindOf(entitySet.EntityType)).ToList();
                if (possibleTypes.Count == 1)
                {
                    entityType = possibleTypes[0];
                    return true;
                }

                string typeName = null;
                if (entitySet.EntityType.HasStream())
                {
                    typeName = request.GetHeaderValueIfExists(HttpHeaders.MediaLinkEntryEntityTypeHint);
                }
                else if (request.Body != null && request.Body.RootElement.ElementType == ODataPayloadElementType.EntityInstance)
                {
                    typeName = ((EntityInstance)request.Body.RootElement).FullTypeName;
                }

                if (typeName != null)
                {
                    entityType = possibleTypes.SingleOrDefault(t => t.FullName == typeName);
                    return entityType != null;
                }
            }

            entityType = null;
            return false;
        }
        private DataServiceProtocolVersion CalculateDataServiceProtocolVersion(ODataRequest request, ODataResponse response)
        {
            DataServiceProtocolVersion dataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.DataServiceVersion));
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));

            var responseContentType = response.GetHeaderValueIfExists(HttpHeaders.ContentType);
            if (responseContentType != null)
            {
                if (responseContentType.StartsWith(MimeTypes.ApplicationJsonODataLightNonStreaming, StringComparison.OrdinalIgnoreCase) ||
                    responseContentType.StartsWith(MimeTypes.ApplicationJsonODataLightStreaming, StringComparison.OrdinalIgnoreCase))
                {
                    return DataServiceProtocolVersion.V4;
                }
            }

            if (response.StatusCode.IsError())
            {
                return DataServiceProtocolVersion.V4;
            }

            DataServiceProtocolVersion expectedVersion = DataServiceProtocolVersion.V4;
            
            // Apply minDsv if MPV > V2
            if (maxDataServiceVersion != DataServiceProtocolVersion.Unspecified && this.maxProtocolVersion >= maxDataServiceVersion)
            {
                expectedVersion = maxDataServiceVersion;
            }
            else
            {
                expectedVersion = this.maxProtocolVersion;
            }

            // If body of a response is empty, the version is V1 unless it has prefer header.
            if (!this.IsResponseBodyEmpty(response))
            {
                if (request.Uri.IsMetadata())
                {
                    // metadata payloads are not handled by the normal payload element visitor, but the response header will match the model version exactly
                    expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.ModelVersionCalculator.CalculateProtocolVersion(this.model));
                }
                else
                {
                    // GET requests are versioned based on the URI because type information is not known until serialization
                    if (request.GetEffectiveVerb() == HttpVerb.Get || request.Uri.IsServiceOperation() || request.Uri.IsAction())
                    {
                        expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.UriVersionCalculator.CalculateProtocolVersion(request.Uri, response.Headers[HttpHeaders.ContentType], this.maxProtocolVersion, dataServiceVersion, maxDataServiceVersion));
                    }

                    // Post and update requests are versioned based on the specific instance
                    if (response.RootElement != null)
                    {
                        expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.PayloadElementVersionCalculator.CalculateProtocolVersion(response.RootElement, response.Headers[HttpHeaders.ContentType], this.maxProtocolVersion, maxDataServiceVersion));
                    }
                }
            }
            else
            {
                if (request.Uri.IsAction())
                {
                    expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.UriVersionCalculator.CalculateProtocolVersion(request.Uri, response.GetHeaderValueIfExists(HttpHeaders.ContentType), this.maxProtocolVersion, dataServiceVersion, maxDataServiceVersion));
                }
            }

            // NOTE: the prefer verifier will ensure that this header is present if it should be, so our only concern here
            // is that the version is >= V3 if it is present
            if (response.Headers.ContainsKey(HttpHeaders.PreferenceApplied))
            {
                expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4);
            }

            return expectedVersion;
        } 
        /// <summary>
        /// Calculates the ResourceStringInformation based on the ODataRequest and maxProtocol version to determine if this i
        /// </summary>
        /// <param name="request">Request to calculate from</param>
        /// <param name="maxProtocolVersion">Max Protocol version of the server</param>
        /// <param name="expectedErrorMessage">Calculated Version Error information</param>
        /// <returns>boolean value of if a Error ResourceString Information was calculated or not</returns>
        public bool TryCalculateError(ODataRequest request, DataServiceProtocolVersion maxProtocolVersion, out ExpectedErrorMessage expectedErrorMessage)
        {
            ExceptionUtilities.CheckArgumentNotNull(request, "request");

            expectedErrorMessage = null;

            DataServiceProtocolVersion dataServiceVersion    = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.DataServiceVersion));
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));

            if (dataServiceVersion == DataServiceProtocolVersion.Unspecified)
            {
                dataServiceVersion = VersionHelper.CalculateDataServiceVersionIfNotSpecified(maxProtocolVersion, maxDataServiceVersion);
            }

            if (TryCalculateDataServiceVersionTooHighError(dataServiceVersion, maxProtocolVersion, out expectedErrorMessage))
            {
                return(true);
            }

            string contentType = request.GetHeaderValueIfExists(HttpHeaders.ContentType);
            string acceptType  = request.GetHeaderValueIfExists(HttpHeaders.Accept);

            if (contentType == null)
            {
                contentType = MimeTypes.Any;
            }

            if (acceptType == null)
            {
                acceptType = MimeTypes.Any;
            }

            // Do Uri processing first
            if (this.TryCalculateODataUriProcessingError(request, maxDataServiceVersion, maxProtocolVersion, acceptType, out expectedErrorMessage))
            {
                return(true);
            }

            // Now check metadata of what the request should look like, will it cause a version bump greater than the DSV
            EntitySet expectedEntitySet = null;

            if (request.Uri.TryGetExpectedEntitySet(out expectedEntitySet))
            {
                DataServiceProtocolVersion entitySetUriVersion = CalculateEntitySetUriSegmentRequestVersion(request, expectedEntitySet, maxProtocolVersion, maxDataServiceVersion, contentType);
                if (TryCalculateVersionError(entitySetUriVersion, dataServiceVersion, maxProtocolVersion, out expectedErrorMessage))
                {
                    return(true);
                }
            }

            // First ensure that the version is greater than mpv
            if (maxProtocolVersion < dataServiceVersion)
            {
                expectedErrorMessage = new ExpectedErrorMessage(DataServiceRequestVersionMustBeLessThanMPV, dataServiceVersion.ConvertToHeaderFormat(), maxProtocolVersion.ConvertToHeaderFormat());
                return(true);
            }

            // Now review the version of the payload and create the right errors
            if (this.TryCalculateODataResponseError(request, dataServiceVersion, maxDataServiceVersion, maxProtocolVersion, out expectedErrorMessage))
            {
                return(true);
            }

            // Now check for any errors from reading the payload
            return(TryCalculateReaderError(request, dataServiceVersion, this.StringResourceVerifiers, this.MetadataResolver, out expectedErrorMessage));
        }
Ejemplo n.º 10
0
        private DataServiceProtocolVersion CalculateDataServiceProtocolVersion(ODataRequest request, ODataResponse response)
        {
            DataServiceProtocolVersion dataServiceVersion    = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.DataServiceVersion));
            DataServiceProtocolVersion maxDataServiceVersion = VersionHelper.ConvertToDataServiceProtocolVersion(request.GetHeaderValueIfExists(HttpHeaders.MaxDataServiceVersion));

            var responseContentType = response.GetHeaderValueIfExists(HttpHeaders.ContentType);

            if (responseContentType != null)
            {
                if (responseContentType.StartsWith(MimeTypes.ApplicationJsonODataLightNonStreaming, StringComparison.OrdinalIgnoreCase) ||
                    responseContentType.StartsWith(MimeTypes.ApplicationJsonODataLightStreaming, StringComparison.OrdinalIgnoreCase))
                {
                    return(DataServiceProtocolVersion.V4);
                }
            }

            if (response.StatusCode.IsError())
            {
                return(DataServiceProtocolVersion.V4);
            }

            DataServiceProtocolVersion expectedVersion = DataServiceProtocolVersion.V4;

            // Apply minDsv if MPV > V2
            if (maxDataServiceVersion != DataServiceProtocolVersion.Unspecified && this.maxProtocolVersion >= maxDataServiceVersion)
            {
                expectedVersion = maxDataServiceVersion;
            }
            else
            {
                expectedVersion = this.maxProtocolVersion;
            }

            // If body of a response is empty, the version is V1 unless it has prefer header.
            if (!this.IsResponseBodyEmpty(response))
            {
                if (request.Uri.IsMetadata())
                {
                    // metadata payloads are not handled by the normal payload element visitor, but the response header will match the model version exactly
                    expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.ModelVersionCalculator.CalculateProtocolVersion(this.model));
                }
                else
                {
                    // GET requests are versioned based on the URI because type information is not known until serialization
                    if (request.GetEffectiveVerb() == HttpVerb.Get || request.Uri.IsServiceOperation() || request.Uri.IsAction())
                    {
                        expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.UriVersionCalculator.CalculateProtocolVersion(request.Uri, response.Headers[HttpHeaders.ContentType], this.maxProtocolVersion, dataServiceVersion, maxDataServiceVersion));
                    }

                    // Post and update requests are versioned based on the specific instance
                    if (response.RootElement != null)
                    {
                        expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.PayloadElementVersionCalculator.CalculateProtocolVersion(response.RootElement, response.Headers[HttpHeaders.ContentType], this.maxProtocolVersion, maxDataServiceVersion));
                    }
                }
            }
            else
            {
                if (request.Uri.IsAction())
                {
                    expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, this.UriVersionCalculator.CalculateProtocolVersion(request.Uri, response.GetHeaderValueIfExists(HttpHeaders.ContentType), this.maxProtocolVersion, dataServiceVersion, maxDataServiceVersion));
                }
            }

            // NOTE: the prefer verifier will ensure that this header is present if it should be, so our only concern here
            // is that the version is >= V3 if it is present
            if (response.Headers.ContainsKey(HttpHeaders.PreferenceApplied))
            {
                expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4);
            }

            return(expectedVersion);
        }