コード例 #1
0
        internal static ODataUri ConstructODataUriWithoutActionInformation(IEnumerable <EntitySet> entitySets, ODataUri uri)
        {
            var segmentsToInclude = new List <ODataUriSegment>();
            ServiceOperationAnnotation serviceOperationAnnotation = null;
            string setName = null;

            foreach (var segment in uri.Segments)
            {
                var functionSegment = segment as FunctionSegment;
                if (functionSegment != null && functionSegment.Function.IsAction())
                {
                    serviceOperationAnnotation = functionSegment.Function.Annotations.OfType <ServiceOperationAnnotation>().Single();
                    var toggleBooleanAnnotation = functionSegment.Function.Annotations.OfType <ToggleBoolPropertyValueActionAnnotation>().SingleOrDefault();

                    if (toggleBooleanAnnotation != null)
                    {
                        setName = toggleBooleanAnnotation.SourceEntitySet;
                    }

                    break;
                }

                segmentsToInclude.Add(segment);
            }

            if (!serviceOperationAnnotation.BindingKind.IsBound())
            {
                ExceptionUtilities.CheckObjectNotNull(setName, "Cannot find the set name that the action starts from");
                var sourceEntitySet = entitySets.Single(es => es.Name == setName);
                segmentsToInclude.Add(new EntitySetSegment(sourceEntitySet));
            }

            var actionlessODataUri = new ODataUri(segmentsToInclude);

            actionlessODataUri.CustomQueryOptions = uri.CustomQueryOptions;
            actionlessODataUri.Filter             = uri.Filter;
            actionlessODataUri.InlineCount        = uri.InlineCount;
            actionlessODataUri.OrderBy            = uri.OrderBy;
            actionlessODataUri.Skip      = uri.Skip;
            actionlessODataUri.SkipToken = uri.SkipToken;
            actionlessODataUri.Top       = uri.Top;
            EntitySet expectedEntitySet = null;

            ExceptionUtilities.Assert(actionlessODataUri.TryGetExpectedEntitySet(out expectedEntitySet), "Expected entity set not found");

            // expand all navigations for actionlessODataUri so that we do not need to send additional request when calculating expected action result
            foreach (NavigationProperty navigation in expectedEntitySet.EntityType.NavigationProperties)
            {
                actionlessODataUri.ExpandSegments.Add(new List <ODataUriSegment>()
                {
                    new NavigationSegment(navigation)
                });
            }

            return(actionlessODataUri);
        }
コード例 #2
0
ファイル: VersionHelper.cs プロジェクト: zhonli/odata.net
        internal static DataServiceProtocolVersion CalculateUriMinRequestProtocolVersion(ODataUri requestUri, string contentType, DataServiceProtocolVersion maxProtocolVersion, DataServiceProtocolVersion maxDataServiceVersion)
        {
            DataServiceProtocolVersion expectedVersion = DataServiceProtocolVersion.V4;

            string inlineCount;

            if (requestUri.TryGetInlineCountValue(out inlineCount))
            {
                expectedVersion = expectedVersion.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
            }

            if (requestUri.SelectSegments.Count > 0)
            {
                expectedVersion = expectedVersion.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
            }

            if (requestUri.HasAnyOrAllInFilter())
            {
                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
            {
                EntitySet expectedEntitySet = null;
                if (requestUri.TryGetExpectedEntitySet(out expectedEntitySet))
                {
                    List <DataServiceProtocolVersion> dataServiceProtocolVersions = GetEntityTypes(expectedEntitySet).Select(et => et.CalculateEntityPropertyMappingProtocolVersion(VersionCalculationType.Request, contentType, maxProtocolVersion, maxDataServiceVersion)).ToList();
                    dataServiceProtocolVersions.Add(expectedVersion);
                    expectedVersion = VersionHelper.GetMaximumVersion(dataServiceProtocolVersions.ToArray());
                }
            }

            return(expectedVersion);
        }
コード例 #3
0
        internal static bool ResponseMightIncludeNextLink(ODataUri uri)
        {
            var payloadsWithNextLinks = new[] { ODataPayloadElementType.EntitySetInstance, ODataPayloadElementType.LinkCollection };
            var expectedPayloadType   = uri.GetExpectedPayloadType();

            if (!payloadsWithNextLinks.Contains(expectedPayloadType))
            {
                return(false);
            }

            EntitySet expectedSet;

            ExceptionUtilities.Assert(uri.TryGetExpectedEntitySet(out expectedSet), "Could not get expected entity set");

            var pageSize = expectedSet.GetEffectivePageSize();

            if (!pageSize.HasValue)
            {
                return(false);
            }

            // if the value of $top is less than 1 page size, no next link will be included
            return(!uri.Top.HasValue || uri.Top.Value > pageSize.Value);
        }
コード例 #4
0
        /// <summary>
        /// Returns the error expected for the Query
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <param name="usesClientQueryable">Whether the client uri is build from a Client Linq expression or not</param>
        /// <param name="clientMaxProtocolVersion">Client Max Protocol Version</param>
        /// <param name="maxProtocolVersion">Max Protocol version of the server</param>
        /// <returns> a versioning error at the Client level</returns>
        public ExpectedClientErrorBaseline CalculateExpectedClientVersionError(QueryExpression expression, bool usesClientQueryable, DataServiceProtocolVersion clientMaxProtocolVersion, DataServiceProtocolVersion maxProtocolVersion)
        {
            ExceptionUtilities.CheckArgumentNotNull(expression, "expression");
            ExceptionUtilities.CheckAllRequiredDependencies(this);

            DataServiceProtocolVersion expectedDataServiceVersion = DataServiceProtocolVersion.Unspecified;
            DataServiceProtocolVersion minRequiredRequestVersion  = DataServiceProtocolVersion.Unspecified;

            ExpectedErrorMessage errorInformation;

            // If the Client Queryable interface is not used to build the expression that is run then no error can happen at this stage
            // There can only be a protocol error from the server if there is no client error
            var serverExpression = this.ClientSideProjectionReplacer.ReplaceClientSideProjections(expression);

            ODataUri odataUri = this.QueryToODataUriConverter.ComputeUri(serverExpression);

            // Predict what the Client will generate for the data service version, if we are not using client.linq its unspecified otherwise calculate it
            if (usesClientQueryable)
            {
                ExpectedClientErrorBaseline expectedErrorIfTooLow;
                minRequiredRequestVersion = this.CalculateExpectedClientMinRequestVersion(odataUri, out expectedErrorIfTooLow);
                if (minRequiredRequestVersion > clientMaxProtocolVersion)
                {
                    if (expectedErrorIfTooLow == null)
                    {
                        errorInformation      = new ExpectedErrorMessage("Context_RequestVersionIsBiggerThanProtocolVersion", minRequiredRequestVersion.ConvertToHeaderFormat(), clientMaxProtocolVersion.ConvertToHeaderFormat());
                        expectedErrorIfTooLow = new ExpectedClientErrorBaseline(typeof(InvalidOperationException), false, errorInformation);
                    }

                    return(expectedErrorIfTooLow);
                }

                EntitySet expectedEntitySet = null;
                if (odataUri.TryGetExpectedEntitySet(out expectedEntitySet))
                {
                    DataServiceProtocolVersion entitySetVersion = expectedEntitySet.CalculateEntitySetProtocolVersion(MimeTypes.ApplicationAtomXml, VersionCalculationType.Request, maxProtocolVersion, clientMaxProtocolVersion);

                    // Client will create a DSV based on the following pieces, metadata of the query based on sets it goes through, uri contructs (select, count, inlinecount, etc)
                    // and headers (like DataServiceResponsePreference). In order to mimic this client behavior I will get the metadata version and a version
                    // from the minrequestVersion and take the max. MinRequest deals with Uri and headers, metadata the metadata.
                    expectedDataServiceVersion = VersionHelper.GetMaximumVersion(minRequiredRequestVersion, entitySetVersion);
                }
            }

            ODataRequest request = new ODataRequest(this.ODataUriToStringConverter)
            {
                Uri     = odataUri,
                Verb    = HttpVerb.Get,
                Headers =
                {
                    { HttpHeaders.DataServiceVersion,    expectedDataServiceVersion.ConvertToHeaderFormat() },
                    { HttpHeaders.MaxDataServiceVersion, clientMaxProtocolVersion.ConvertToHeaderFormat()   },
                    { HttpHeaders.Accept,                MimeTypes.ApplicationAtomXml                       }
                }
            };

            if (this.ODataRequestVersionResourceErrorCalculator.TryCalculateError(request, maxProtocolVersion, out errorInformation))
            {
                return(new ExpectedClientErrorBaseline(typeof(DSClient.DataServiceQueryException), true, errorInformation));
            }

            return(null);
        }
コード例 #5
0
ファイル: ODataUriEvaluator.cs プロジェクト: zhonli/odata.net
        /// <summary>
        /// Processes the given uri and produces an expected value according to the conventions of an OData server implementation
        /// </summary>
        /// <param name="uri">The uri to process</param>
        /// <param name="applySelectAndExpand">A value indicating whether or not $select and $expand should be applied to the query values</param>
        /// <param name="applyPaging">A value indicating whether server-driven paging should be applied to the query values</param>
        /// <returns>The value resulting from processing the uri</returns>
        public QueryValue Evaluate(ODataUri uri, bool applySelectAndExpand, bool applyPaging)
        {
            this.applyPagingInExpands = applyPaging;
            ExceptionUtilities.CheckArgumentNotNull(uri, "uri");
            ExceptionUtilities.CheckCollectionNotEmpty(uri.Segments, "uri.Segments");
            ExceptionUtilities.CheckAllRequiredDependencies(this);

            this.currentUri = uri;
            this.shouldLastSegmentBeSingleton = false;

            applyPaging &= uri.TryGetExpectedEntitySet(out this.expectedEntitySet);

            if (applyPaging)
            {
                // compute the expected page size for this request based on the existence of a universal page size or set-specific page size
                this.expectedPageSize = this.expectedEntitySet.GetEffectivePageSize();
            }
            else
            {
                this.expectedPageSize = null;
            }

            var query = this.BuildQueryFromSegments();

            ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);

            // we explicitly do not process expand or select here because they do not affect the number of rows returned or their ordering
            query = this.ProcessFilter(query);
            ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);

            if (uri.IsEntitySet())
            {
                // TODO: skip-token processing should happen before ordering
                query = this.ProcessOrderBy(query);
                ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);

                query = this.ProcessSkipAndTop(query);
                ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);
            }

            // handle $count requests
            if (uri.IsCount())
            {
                query = query.LongCount();
            }

            // need to resolve types since we constructed new QueryExpression tree
            var resolvedQuery = this.QueryResolver.Resolve(query);

            var value = this.Evaluator.Evaluate(resolvedQuery);

            ExceptionUtilities.CheckObjectNotNull(value, "Could not evaluate query '{0}'", query);
            ExceptionUtilities.Assert(value.EvaluationError == null, "Query evaluation produced an error: {0}", value.EvaluationError);

            // post-process the result to defer properties that were not expanded
            if (applySelectAndExpand)
            {
                value = this.ApplySelectAndExpand(uri, value);
            }

            // fixup for key expressions that should return singletons
            if (this.shouldLastSegmentBeSingleton)
            {
                value = EnsureLastSegmentIsSingletonOrNull(value);
            }

            this.currentUri        = null;
            this.expectedEntitySet = null;
            this.expectedPageSize  = null;

            return(value);
        }