Ejemplo n.º 1
0
        internal static DataServiceProtocolVersion CalculateUriResponseMinProtocolVersion(ODataUri requestUri, string contentType, DataServiceProtocolVersion maxProtocolVersion, DataServiceProtocolVersion maxDataServiceVersion)
        {
            DataServiceProtocolVersion expectedVersion = DataServiceProtocolVersion.V4;

            if (requestUri.IncludesInlineCountAllPages())
            {
                expectedVersion = expectedVersion.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
            }

            if (requestUri.IsCount())
            {
                expectedVersion = expectedVersion.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
            }
            else if (requestUri.IsProperty())
            {
                var propertySegment = requestUri.LastSegment as PropertySegment;
                expectedVersion = expectedVersion.IncreaseVersionIfRequired(propertySegment.Property.CalculateProtocolVersion());
            }
            else if (!requestUri.IsNamedStream())
            {
                // Check service operations returning non-entity types
                if (requestUri.IsServiceOperation())
                {
                    var      serviceOpSegment = requestUri.Segments.OfType <FunctionSegment>().Single();
                    DataType returnType       = serviceOpSegment.Function.ReturnType;

                    // Service ops returning complex values or bags of complex values, where the complex type has bag properties, are v3
                    var collectionType = returnType as CollectionDataType;
                    if (collectionType != null)
                    {
                        // for service operations, the fact that a collection is returned does not mean it is a multivalue
                        // so we unwrap the element type before calculating the version
                        returnType = collectionType.ElementDataType;
                    }

                    expectedVersion = expectedVersion.IncreaseVersionIfRequired(returnType.CalculateDataTypeVersion());
                }

                // Check entity types
                List <DataServiceProtocolVersion> dataServiceProtocolVersions = new List <DataServiceProtocolVersion>();
                dataServiceProtocolVersions.Add(expectedVersion);

                if (!(requestUri.IsEntityReferenceLink() || requestUri.IsPropertyValue()))
                {
                    foreach (EntitySet entitySet in requestUri.GetAllEntitySetsIncludingExpands())
                    {
                        DataServiceProtocolVersion entitySetVersion = entitySet.CalculateEntitySetProtocolVersion(contentType, VersionCalculationType.Response, maxProtocolVersion, maxDataServiceVersion);
                        dataServiceProtocolVersions.Add(entitySetVersion);
                        if (entitySetVersion > maxDataServiceVersion)
                        {
                            return(VersionHelper.GetMaximumVersion(dataServiceProtocolVersions.ToArray()));
                        }
                    }
                }
            }

            return(expectedVersion);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Find out whether to use payload for client verification
        /// </summary>
        /// <param name="queryUri">The request uri</param>
        /// <returns>Whether to use payload for client verification</returns>
        private bool ShouldUsePayloadDrivenVerification(ODataUri queryUri)
        {
            if (queryUri.IsAction())
            {
                return(true);
            }

            if (queryUri.IsServiceOperation())
            {
                FunctionSegment functionSegment = queryUri.Segments.OfType <FunctionSegment>().Last();
                return(!functionSegment.Function.Annotations.OfType <FunctionBodyAnnotation>().Single().IsRoot);
            }

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Generates the expected next link for a top-level feed
        /// </summary>
        /// <param name="requestUri">The request URI.</param>
        /// <param name="pageSize">The page size.</param>
        /// <param name="lastEntityValue">The last entity value.</param>
        /// <returns>
        /// The expected next link
        /// </returns>
        public string GenerateNextLink(ODataUri requestUri, int pageSize, QueryStructuralValue lastEntityValue)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestUri, "requestUri");
            ExceptionUtilities.CheckArgumentNotNull(lastEntityValue, "lastEntityValue");

            var queryBasedUri = requestUri as QueryBasedODataUri;

            ExceptionUtilities.CheckObjectNotNull(queryBasedUri, "Only uris which were generated from queries are supported");

            var skipTokenValues = new List <object>();

            foreach (var keySelector in queryBasedUri.OrderByExpressions.SelectMany(o => o.KeySelectors))
            {
                skipTokenValues.Add(this.EvaluateLambdaForEntity(lastEntityValue, keySelector));
            }

            foreach (var keyProperty in lastEntityValue.Type.Properties.Where(p => p.IsPrimaryKey))
            {
                skipTokenValues.Add(lastEntityValue.GetScalarValue(keyProperty.Name).Value);
            }

            var skiptoken = this.BuildSkipTokenFromValues(skipTokenValues);

            // copy request uri segments exactly
            var nextLinkUri = new ODataUri(requestUri.Segments);

            // copy over $orderby, $filter, $expand, $select, and $inlinecount
            nextLinkUri.OrderBy        = ModifyQueryOptionToMatchProduct(requestUri.OrderBy);
            nextLinkUri.Filter         = ModifyQueryOptionToMatchProduct(requestUri.Filter);
            nextLinkUri.ExpandSegments = requestUri.ExpandSegments;
            nextLinkUri.SelectSegments = requestUri.SelectSegments;

            string inlineCountValue;

            if (requestUri.TryGetInlineCountValue(out inlineCountValue))
            {
                nextLinkUri.InlineCount = inlineCountValue;
            }

            // add the $skiptoken generated above
            nextLinkUri.SkipToken = skiptoken;

            // generate a new $top value
            if (requestUri.Top.HasValue)
            {
                var top = requestUri.Top.Value - pageSize;
                if (top > 0)
                {
                    nextLinkUri.Top = top;
                }
            }

            if (requestUri.IsServiceOperation())
            {
                var functionSegment = requestUri.Segments.OfType <FunctionSegment>().Last();
                foreach (var paramName in functionSegment.Function.Parameters.Select(p => p.Name))
                {
                    string paramValue;
                    if (requestUri.CustomQueryOptions.TryGetValue(paramName, out paramValue))
                    {
                        nextLinkUri.CustomQueryOptions[paramName] = paramValue;
                    }
                }
            }

            return(this.UriToStringConverter.ConvertToString(nextLinkUri));
        }