public void FilterBySpatialFunctionWithLiterals()
        {
            Tuple <string, int>[] testCases = new Tuple <string, int>[] {
                Tuple.Create("eq 1", 4),
                Tuple.Create("ne 2", 4),
                Tuple.Create("gt 2", 0),
            };

            this.serviceFactory.SetRequestUri("Entities");
            string resourcePath = this.serviceFactory.RequestUri.OriginalString;

            foreach (var t in testCases)
            {
                this.serviceFactory.ClearQueryArgument();
                this.serviceFactory.AddQueryArgument("$filter", "geo.distance(geography'SRID=1234;POINT(20 10)', geography'SRID=1234;POINT(20 10)') " + t.Item1);
                this.serviceFactory.SetRequestUri(resourcePath + "?$filter=geo.distance(geography'SRID=1234;POINT(20 10)', geography'SRID=1234;POINT(20 10)') " + t.Item1);
                var service = this.serviceFactory.CreateService();

                RequestDescription d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

                Action <GeographyPoint> verifyPoint =
                    p =>
                {
                    Assert.AreEqual(20.0, p.Longitude);
                    Assert.AreEqual(10.0, p.Latitude);
                };

                RunSpatialDistanceFilterTest(d, verifyPoint, verifyPoint, 1.0, t.Item2);
            }
        }
示例#2
0
        private ODataStreamReferenceValue GetMediaResource(object element, ResourceType entityResourceType, string title, Uri relativeUri)
        {
            ODataStreamReferenceValue value2 = null;

            if (entityResourceType.IsMediaLinkEntry)
            {
                string str;
                Uri    uri;
                string str2;
                base.Service.StreamProvider.GetStreamDescription(element, null, base.Service.OperationContext, out str, out uri, out str2);
                Uri uri2 = RequestUriProcessor.AppendEscapedSegment(relativeUri, "$value");
                value2 = new ODataStreamReferenceValue {
                    EditLink    = uri2,
                    ContentType = str2,
                    ReadLink    = uri ?? uri2
                };
                AtomStreamReferenceMetadata metadata2 = new AtomStreamReferenceMetadata();
                AtomLinkMetadata            metadata3 = new AtomLinkMetadata {
                    Title = title
                };
                metadata2.EditLink = metadata3;
                AtomStreamReferenceMetadata annotation = metadata2;
                value2.SetAnnotation <AtomStreamReferenceMetadata>(annotation);
                if (!string.IsNullOrEmpty(str))
                {
                    value2.ETag = str;
                }
            }
            return(value2);
        }
        private void RunSpatialExpressionTest(string queryOption, string queryOptionValue, Expression <Func <IQueryable <TestEntityType>, IQueryable <TestEntityType> > > expectedExpressionPattern)
        {
            this.serviceFactory.SetRequestUri("Entities?" + queryOption + "=" + queryOptionValue);
            var service = this.serviceFactory.CreateService();

            var d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

            var actualQueryableMethodExpression = (MethodCallExpression)d.RequestExpression;

            var expectedString = expectedExpressionPattern.ToString();
            var actualString   = actualQueryableMethodExpression.ToString();

            Console.WriteLine();
            Console.WriteLine("Expected: " + expectedString);
            Console.WriteLine("Actual: " + actualString);

            // get the portion of the expected string which represents the 'root'. it will look something like 'q => q.'
            var parameterString = expectedExpressionPattern.Parameters.Single().ToString();

            parameterString = parameterString + " => " + parameterString + ".";
            expectedString  = expectedString.Substring(parameterString.Length);

            // just verify that the .Where or .OrderBy call matches. We don't verify the root of the tree.
            Assert.IsTrue(actualString.EndsWith(expectedString));
        }
        public void FilterCompareSpatialLiterals()
        {
            var tests = new[]
            {
                new { Operator = "eq", ErrorName = "Equal" },
                new { Operator = "ne", ErrorName = "NotEqual" },
                new { Operator = "lt", ErrorName = "LessThan" },
                new { Operator = "gt", ErrorName = "GreaterThan" },
                new { Operator = "le", ErrorName = "LessThanOrEqual" },
                new { Operator = "ge", ErrorName = "GreaterThanOrEqual" }
            };

            this.serviceFactory.SetRequestUri("Entities");

            foreach (var test in tests)
            {
                // spatial literal vs spatial literal
                this.serviceFactory.SetRequestUri("Entities?$filter=geography'POINT(10 20)' " + test.Operator + " geography'SRID=1234;POINT(10 20)'");

                var service = this.serviceFactory.CreateService();

                Action processUri = () => RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);
                processUri.ShouldThrow <DataServiceException>().WithMessage(Microsoft.OData.Core.Strings.MetadataBinder_IncompatibleOperandsError("Edm.GeographyPoint", "Edm.GeographyPoint", test.ErrorName));
            }
        }
示例#5
0
        /// <summary>
        /// Reads the input request payload and returns the WCF DS value representation of it.
        /// </summary>
        /// <param name="segmentInfo">Info about the request to read. For entity reference requests this is null.</param>
        /// <returns>The WCF DS representation of the value read. For entity reference link this is the Uri of the link.</returns>
        protected override object Read(SegmentInfo segmentInfo)
        {
            Debug.Assert(segmentInfo == null, "segmentInfo == null");
            Debug.Assert(this.RequestDescription.LinkUri, "The EntityReferenceLinkDeserializer only supports $ref payloads.");

            ODataEntityReferenceLink entityReferenceLink = this.MessageReader.ReadEntityReferenceLink();

            Debug.Assert(entityReferenceLink != null, "ReadEntityReferenceLink should never return null.");
            Uri entityReferenceUri = entityReferenceLink.Url;

            Debug.Assert(entityReferenceUri != null, "The Url of the entity reference link should never be null.");
#pragma warning disable 618
            AssertReaderFormatIsExpected(this.MessageReader, ODataFormat.Atom, ODataFormat.Json);
#pragma warning restore 618

            // We must fail on empty URI
            string entityReferenceUriAsString = UriUtil.UriToString(entityReferenceUri);
            if (string.IsNullOrEmpty(entityReferenceUriAsString))
            {
                throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_MissingUriForLinkOperation);
            }

            // Resolve the URI against the service
            return(RequestUriProcessor.GetAbsoluteUriFromReference(entityReferenceUri, this.Service.OperationContext.AbsoluteServiceUri));
        }
示例#6
0
        /// <summary>
        /// Get the ODataStreamReferenceValue instance containing the metadata for named stream property.
        /// </summary>
        /// <param name="entityToSerialize">Entity that is currently being serialized.</param>
        /// <param name="namedStreamProperty">Named stream property for which the link element needs to be written.</param>
        /// <returns>
        /// An instance of ODataStreamReferenceValue containing all the metadata about the named stream property.
        /// </returns>
        private ODataStreamReferenceValue GetNamedStreamPropertyValue(EntityToSerialize entityToSerialize, ResourceProperty namedStreamProperty)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(namedStreamProperty != null, "namedStreamProperty != null");
            Debug.Assert(namedStreamProperty.IsOfKind(ResourcePropertyKind.Stream), "namedStreamProperty.IsOfKind(ResourcePropertyKind.Stream)");

            string mediaETag;
            Uri    readStreamUri;
            string mediaContentType;

            this.Service.StreamProvider.GetStreamDescription(entityToSerialize.Entity, namedStreamProperty, this.Service.OperationContext, out mediaETag, out readStreamUri, out mediaContentType);
            Debug.Assert(WebUtil.IsETagValueValid(mediaETag, true), "WebUtil.IsETagValueValid(mediaETag, true)");

            ODataStreamReferenceValue streamReferenceValue = new ODataStreamReferenceValue();

            this.PayloadMetadataPropertyManager.SetContentType(streamReferenceValue, mediaContentType);

            this.PayloadMetadataPropertyManager.SetEditLink(
                streamReferenceValue,
                () =>
            {
                Uri relativeUri = entityToSerialize.SerializedKey.RelativeEditLink;
                return(RequestUriProcessor.AppendUnescapedSegment(relativeUri, namedStreamProperty.Name));
            });

            if (!string.IsNullOrEmpty(mediaETag))
            {
                this.PayloadMetadataPropertyManager.SetETag(streamReferenceValue, mediaETag);
            }

            // Note if readStreamUri is null, the self link for the named stream will be omitted.
            this.PayloadMetadataPropertyManager.SetReadLink(streamReferenceValue, () => readStreamUri);
            return(streamReferenceValue);
        }
示例#7
0
        private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url)
        {
            base.CheckAndIncrementObjectCount();
            RequestDescription description = RequestUriProcessor.ProcessRequestUri(RequestUriProcessor.GetAbsoluteUriFromReference(url, base.Service.OperationContext), base.Service, true);

            if ((this.ContentFormat == ContentFormat.Atom) && !description.IsSingleResult)
            {
                if ((navigationProperty != null) && (navigationProperty.Kind == ResourcePropertyKind.ResourceReference))
                {
                    throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name));
                }
            }
            else
            {
                object propertyValue = base.Service.GetResource(description, description.SegmentInfos.Length - 1, null);
                if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
                {
                    base.Updatable.SetReference(entityResource, navigationProperty.Name, propertyValue);
                }
                else
                {
                    WebUtil.CheckResourceExists(propertyValue != null, description.LastSegmentInfo.Identifier);
                    base.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, propertyValue);
                }
            }
        }
示例#8
0
        /// <summary>
        /// Initializes a new dummy host for the batch request.
        /// This host represents a single operation in the batch.
        /// </summary>
        /// <param name="absoluteServiceUri">Absolute Uri to the service.</param>
        /// <param name="operationMessage">The request message representing a batch operation to wrap.</param>
        /// <param name="contentId">Content id for the given operation host.</param>
        /// <param name="writer">ODataBatchWriter instance.</param>
        /// <param name="odataMaxVersion">OData-MaxVersion header on the batch request. If the OData-MaxVersion header is not specified in the current operation, we default to the MaxDSV from the batch level.</param>
        internal BatchServiceHost(Uri absoluteServiceUri, IODataRequestMessage operationMessage, string contentId, ODataBatchWriter writer, Version odataMaxVersion)
            : this(writer)
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");
            Debug.Assert(operationMessage != null, "operationMessage != null");
            this.absoluteServiceUri = absoluteServiceUri;
            this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(operationMessage.Url, absoluteServiceUri);

            this.requestHttpMethod = operationMessage.Method;
            this.contentId         = contentId;

            foreach (KeyValuePair <string, string> header in operationMessage.Headers)
            {
                this.requestHeaders.Add(header.Key, header.Value);
            }

            // If the MaxDSV header is not specified in the current operation, we default to the MaxDSV from the batch level.
            if (string.IsNullOrEmpty(this.requestHeaders[XmlConstants.HttpODataMaxVersion]))
            {
                Debug.Assert(odataMaxVersion != null, "odataMaxVersion != null");
                this.requestHeaders[XmlConstants.HttpODataMaxVersion] = odataMaxVersion.ToString();
            }

            this.requestStream = operationMessage.GetStream();
        }
        public void FilterBySpatialFunctionWithProperties()
        {
            var testCases = new[] {
                Tuple.Create("eq 1", 4),
                Tuple.Create("ne 2", 4),
                Tuple.Create("gt 2", 0),
            };

            foreach (var t in testCases)
            {
                this.serviceFactory.SetRequestUri("Entities?$filter=geo.distance(Point, geography'SRID=1234;POINT(20 10)') " + t.Item1);
                var service = this.serviceFactory.CreateService();

                RequestDescription d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

                Action <GeographyPoint> verifyPoint =
                    p =>
                {
                    Assert.AreEqual(20.0, p.Longitude);
                    Assert.AreEqual(10.0, p.Latitude);
                };

                RunSpatialDistanceFilterTest(d, null, verifyPoint, 1.0, t.Item2);
            }
        }
示例#10
0
        private static ODataAssociationLink GetAssociationLink(Uri relativeUri, ResourceProperty navigationProperty)
        {
            Uri uri = RequestUriProcessor.AppendUnescapedSegment(RequestUriProcessor.AppendEscapedSegment(relativeUri, "$links"), navigationProperty.Name);

            return(new ODataAssociationLink {
                Name = navigationProperty.Name, Url = uri
            });
        }
示例#11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Microsoft.OData.Service.ExpandAndSelectParseResult"/> class.
        /// </summary>
        /// <param name="requestDescription">The request description.</param>
        /// <param name="dataService">The data service.</param>
        internal ExpandAndSelectParseResult(RequestDescription requestDescription, IDataService dataService)
        {
            Debug.Assert(dataService != null, "dataService != null");
            Debug.Assert(dataService.OperationContext != null, "dataService.OperationContext != null");
            Debug.Assert(dataService.OperationContext.RequestMessage != null, "dataService.OperationContext.RequestMessage != null");

            string expand = dataService.OperationContext.RequestMessage.GetQueryStringItem(XmlConstants.HttpQueryStringExpand);

            this.RawSelectQueryOptionValue = dataService.OperationContext.RequestMessage.GetQueryStringItem(XmlConstants.HttpQueryStringSelect);

            ResourceType       targetResourceType = requestDescription.TargetResourceType;
            ResourceSetWrapper targetResourceSet  = requestDescription.TargetResourceSet;

            if (!string.IsNullOrEmpty(expand))
            {
                if (targetResourceType == null || targetResourceType.ResourceTypeKind != ResourceTypeKind.EntityType || targetResourceSet == null)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryExpandOptionNotApplicable);
                }
            }

            if (!string.IsNullOrEmpty(this.RawSelectQueryOptionValue))
            {
                ValidateSelectIsAllowedForRequest(requestDescription);

                // Throw if $select requests have been disabled by the user
                Debug.Assert(dataService.Configuration != null, "dataService.Configuration != null");
                if (!dataService.Configuration.DataServiceBehavior.AcceptProjectionRequests)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.DataServiceConfiguration_ProjectionsNotAccepted);
                }
            }

            MetadataProviderEdmModel model = dataService.Provider.GetMetadataProviderEdmModel();

            var uriParser = RequestUriProcessor.CreateUriParserWithBatchReferenceCallback(dataService, dataService.OperationContext.AbsoluteRequestUri);

            try
            {
                Debug.Assert(model.Mode == MetadataProviderEdmModelMode.Serialization, "Model expected to be in serialization mode by default");
                model.Mode  = MetadataProviderEdmModelMode.SelectAndExpandParsing;
                this.Clause = uriParser.ParseSelectAndExpand();
            }
            catch (ODataException ex)
            {
                throw new DataServiceException(400, null, ex.Message, null, ex);
            }
            finally
            {
                model.Mode = MetadataProviderEdmModelMode.Serialization;
            }

            if (this.Clause != null)
            {
                this.HasExpand = this.Clause.SelectedItems.OfType <ExpandedNavigationSelectItem>().Any();
                this.HasSelect = HasSelectedItemAtAnyLevel(this.Clause);
            }
        }
示例#12
0
        protected override object Read(System.Data.Services.SegmentInfo segmentInfo)
        {
            Uri url = base.MessageReader.ReadEntityReferenceLink().Url;

            if (string.IsNullOrEmpty(CommonUtil.UriToString(url)))
            {
                throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_MissingUriForLinkOperation);
            }
            return(RequestUriProcessor.GetAbsoluteUriFromReference(url, base.Service.OperationContext.AbsoluteServiceUri, base.RequestDescription.RequestVersion));
        }
        public void QuerySpatialProperty()
        {
            this.serviceFactory.SetRequestUri("Entities(0)/Spatial");
            var service = this.serviceFactory.CreateService();

            RequestDescription d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

            Assert.AreEqual(RequestTargetKind.Primitive, d.LastSegmentInfo.TargetKind);
            Assert.AreEqual("Spatial", d.LastSegmentInfo.Identifier);
        }
示例#14
0
 /// <summary>
 /// Constructs a new instance of DataServiceOperationContext object
 /// </summary>
 /// <param name="host">RequestMessage instance for the current operation context.</param>
 internal DataServiceOperationContext(IDataServiceHost host)
 {
     Debug.Assert(host != null, "host != null");
     this.hostInterface   = host;
     this.lazyMetadataUri = new SimpleLazy <Uri>(() =>
     {
         Debug.Assert(this.AbsoluteServiceUri != null, "Cannot get the metadata uri if the absolute service uri is not initialized");
         return(RequestUriProcessor.AppendEscapedSegment(this.AbsoluteServiceUri, XmlConstants.UriMetadataSegment));
     });
 }
        /// <summary>Initializes a new <see cref="RequestExpressionParser"/>.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="requestDescription">RequestDescription instance containing information about the current request being parsed.</param>
        internal RequestExpressionParser(IDataService service, RequestDescription requestDescription)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");

            this.provider = service.Provider;

            this.model = this.provider.GetMetadataProviderEdmModel();

            this.odataUriParser = RequestUriProcessor.CreateUriParserWithBatchReferenceCallback(service, service.OperationContext.AbsoluteRequestUri);
        }
示例#16
0
        protected object GetTargetResourceToBind(Uri referencedUri, bool checkNull)
        {
            System.Data.Services.RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true);
            object obj2 = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null);

            if (checkNull)
            {
                WebUtil.CheckResourceExists(obj2 != null, description.LastSegmentInfo.Identifier);
            }
            return(obj2);
        }
示例#17
0
        internal static Uri GetIdAndEditLink(object resource, ResourceType resourceType, DataServiceProviderWrapper provider, ResourceSetWrapper container, Uri absoluteServiceUri, out Uri id)
        {
            string segmentIdentifier = GetObjectKey(resource, resourceType, provider, container.Name);
            Uri    uri = RequestUriProcessor.AppendEscapedSegment(absoluteServiceUri, segmentIdentifier);

            id = uri;
            if (container.HasNavigationPropertyOrNamedStreamsOnDerivedTypes(provider))
            {
                uri = RequestUriProcessor.AppendUnescapedSegment(uri, resourceType.FullName);
            }
            return(uri);
        }
示例#18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LazySerializedEntityKey"/> class which uses the same syntax for identity and edit link.
        /// </summary>
        /// <param name="lazyRelativeIdentity">The identity as a lazy string relative to the service URI.</param>
        /// <param name="absoluteServiceUri">The absolute service URI.</param>
        /// <param name="editLinkSuffix">The optional suffix to append to the edit link. Null means nothing will be appended.</param>
        internal LazySerializedEntityKey(SimpleLazy <string> lazyRelativeIdentity, Uri absoluteServiceUri, string editLinkSuffix)
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");

            this.lazyAbsoluteEditLinkWithoutSuffix = new SimpleLazy <Uri>(() => RequestUriProcessor.AppendEscapedSegment(absoluteServiceUri, lazyRelativeIdentity.Value));
            this.lazyIdentity         = new SimpleLazy <Uri>(() => this.lazyAbsoluteEditLinkWithoutSuffix.Value, false);
            this.lazyAbsoluteEditLink = AppendLazilyIfNeeded(this.lazyAbsoluteEditLinkWithoutSuffix, editLinkSuffix);

            SimpleLazy <Uri> relativeEdit = new SimpleLazy <Uri>(() => new Uri(lazyRelativeIdentity.Value, UriKind.Relative), false);

            this.lazyRelativeEditLink = AppendLazilyIfNeeded(relativeEdit, editLinkSuffix);
        }
示例#19
0
        /// <summary>
        /// Get the stream reference value for media resource (the default stream of an entity).
        /// </summary>
        /// <param name="entityToSerialize">Entity that is currently being serialized.</param>
        /// <param name="title">The title for the element being written.</param>
        /// <returns>
        /// An instance of ODataStreamReferenceValue containing the metadata about the media resource.
        /// </returns>
        private ODataStreamReferenceValue GetMediaResource(EntityToSerialize entityToSerialize, string title)
        {
            Debug.Assert(entityToSerialize.Entity != null, "element != null");
            Debug.Assert(entityToSerialize.ResourceType != null && entityToSerialize.ResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "type != null && type.ResourceTypeKind == ResourceTypeKind.EntityType");
            Debug.Assert(!string.IsNullOrEmpty(title), "!string.IsNullOrEmpty(title)");

            ODataStreamReferenceValue mediaResource = null;

            // Handle MLE
            if (entityToSerialize.ResourceType.IsMediaLinkEntry)
            {
                string mediaETag;
                Uri    readStreamUri;
                string mediaContentType;

                Debug.Assert(entityToSerialize.ResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "type.ResourceTypeKind == ResourceTypeKind.EntityType");
                this.Service.StreamProvider.GetStreamDescription(entityToSerialize.Entity, null /*null for MLE*/, this.Service.OperationContext, out mediaETag, out readStreamUri, out mediaContentType);
                Debug.Assert(WebUtil.IsETagValueValid(mediaETag, true), "WebUtil.IsETagValueValid(mediaETag, true)");
                Debug.Assert(!string.IsNullOrEmpty(mediaContentType), "!string.IsNullOrEmpty(mediaContentType)");

                mediaResource = new ODataStreamReferenceValue();

                // build the stream's edit link lazily to avoid creating the entity's edit link if it is not needed.
                SimpleLazy <Uri> lazyStreamEditLink = new SimpleLazy <Uri>(() => RequestUriProcessor.AppendEscapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, XmlConstants.UriValueSegment));

                this.PayloadMetadataPropertyManager.SetEditLink(mediaResource, () => lazyStreamEditLink.Value);

                this.PayloadMetadataPropertyManager.SetContentType(mediaResource, mediaContentType);

                // If the stream provider did not provider a read link, then we should use the edit link as the read link.
                this.PayloadMetadataPropertyManager.SetReadLink(mediaResource, () => readStreamUri ?? lazyStreamEditLink.Value);
#pragma warning disable 618
                if (this.contentFormat == ODataFormat.Atom)
#pragma warning restore 618
                {
                    AtomStreamReferenceMetadata mediaResourceAtom = new AtomStreamReferenceMetadata()
                    {
                        EditLink = new AtomLinkMetadata {
                            Title = title
                        }
                    };
                    mediaResource.SetAnnotation(mediaResourceAtom);
                }

                if (!string.IsNullOrEmpty(mediaETag))
                {
                    this.PayloadMetadataPropertyManager.SetETag(mediaResource, mediaETag);
                }
            }

            return(mediaResource);
        }
示例#20
0
        [Ignore] // Currently we have overloads of geog, geogPoint; etc. because EF forces us to use properties of type Geography rather than GeographyPoint.
        public void FilterBySpatialFunctionWrongType()
        {
            this.serviceFactory.SetRequestUri("Entities");

            this.serviceFactory.AddQueryArgument("$filter", "geo.distance(Spatial, SRID=1234;POINT(10 20)) lt 10");
            var service = this.serviceFactory.CreateService();

            Action test = () => RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

            string expectedFunctions = "geo.distance(System.Data.Spatial.Geography.GeographyPoint, System.Data.Spatial.Geography.GeographyPoint)";

            test.ShouldThrow <DataServiceException>().WithMessage(Microsoft.OData.Service.Strings.RequestQueryParser_NoApplicableFunction(
                                                                      "geo.distance",
                                                                      expectedFunctions));
        }
示例#21
0
        /// <summary>
        /// Initializes a new dummy host for the batch request.
        /// This host represents a single operation in the batch.
        /// </summary>
        /// <param name="absoluteServiceUri">absolute Uri to the service</param>
        /// <param name="batchStream">batch stream which contains the header information.</param>
        /// <param name="contentId">content id for the given operation host.</param>
        /// <param name='boundary'>Response separator string.</param>
        /// <param name='writer'>Output writer.</param>
        internal BatchServiceHost(Uri absoluteServiceUri, BatchStream batchStream, string contentId, string boundary, StreamWriter writer)
            : this(boundary, writer)
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");
            Debug.Assert(batchStream != null, "batchStream != null");

            this.absoluteServiceUri = absoluteServiceUri;
            this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(batchStream.ContentUri, absoluteServiceUri);
            this.requestHttpMethod  = GetHttpMethodName(batchStream.State);
            this.requestStream      = batchStream.GetContentStream();
            this.contentId          = contentId;

            foreach (KeyValuePair <string, string> header in batchStream.ContentHeaders)
            {
                this.requestHeaders.Add(header.Key, header.Value);
            }
        }
示例#22
0
        /// <summary>
        /// Gets the target link value for an <see cref="ODataOperation"/>
        /// </summary>
        /// <param name="entityToSerialize">The current entity being serialized.</param>
        /// <param name="operation">The operation to generate the link for.</param>
        /// <param name="entityHasMultipleActionsWithSameName">Whether or not there are multiple operations in the current scope with the same name as the current operation.</param>
        /// <returns>Uri representing link to use for invoking this operation.</returns>
        internal Uri BuildTargetLink(EntityToSerialize entityToSerialize, OperationWrapper operation, bool entityHasMultipleActionsWithSameName)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(operation != null, "operation != null");
            Debug.Assert(operation.BindingParameter != null, "operation.BindingParameter != null");
            Debug.Assert(operation.BindingParameter.ParameterType != null, "operation.BindingParameter.ParameterType != null");

            string targetSegment = operation.GetActionTargetSegmentByResourceType(entityToSerialize.ResourceType, this.namespaceName);

            // If there are multiple operations with the same name, then using the edit link of the entry would cause the target to potentially resolve to the wrong
            // operation. Instead, use the actual binding type of the specific operation.
            if (entityHasMultipleActionsWithSameName)
            {
                Uri editLinkWithBindingType = RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLinkWithoutSuffix, operation.BindingParameter.ParameterType.FullName);
                return(RequestUriProcessor.AppendUnescapedSegment(editLinkWithBindingType, targetSegment));
            }

            return(RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, targetSegment));
        }
示例#23
0
        private ODataStreamReferenceValue GetNamedStreamPropertyValue(object element, ResourceProperty namedStreamProperty, Uri relativeUri)
        {
            string str;
            Uri    uri;
            string str2;

            base.Service.StreamProvider.GetStreamDescription(element, namedStreamProperty, base.Service.OperationContext, out str, out uri, out str2);
            ODataStreamReferenceValue value2 = new ODataStreamReferenceValue {
                ContentType = str2,
                EditLink    = RequestUriProcessor.AppendUnescapedSegment(relativeUri, namedStreamProperty.Name)
            };

            if (!string.IsNullOrEmpty(str))
            {
                value2.ETag = str;
            }
            value2.ReadLink = uri;
            return(value2);
        }
示例#24
0
 internal BatchServiceHost(Uri absoluteServiceUri, IODataRequestMessage operationMessage, string contentId, ODataBatchWriter writer, Version maxDataServiceVersion, Version minDataServiceVersion, Version dataServiceVersion) : this(writer)
 {
     this.absoluteServiceUri = absoluteServiceUri;
     this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(operationMessage.Url, absoluteServiceUri, dataServiceVersion);
     this.requestHttpMethod  = operationMessage.Method;
     this.contentId          = contentId;
     foreach (KeyValuePair <string, string> pair in operationMessage.Headers)
     {
         this.requestHeaders.Add(pair.Key, pair.Value);
     }
     if (string.IsNullOrEmpty(this.requestHeaders["MaxDataServiceVersion"]))
     {
         this.requestHeaders["MaxDataServiceVersion"] = maxDataServiceVersion.ToString();
     }
     if (string.IsNullOrEmpty(this.requestHeaders["MinDataServiceVersion"]))
     {
         this.requestHeaders["MinDataServiceVersion"] = minDataServiceVersion.ToString();
     }
     this.requestStream = operationMessage.GetStream();
 }
        public void FilterSpatialMathOperators()
        {
            var tests = new[]
            {
                new { Operator = "add", ErrorName = "Add" },
                new { Operator = "mul", ErrorName = "Multiply" },
            };

            this.serviceFactory.SetRequestUri("Entities");

            foreach (var test in tests)
            {
                // property vs spatial literal
                this.serviceFactory.SetRequestUri("Entities?$filter=Spatial " + test.Operator + " geography'SRID=1234;POINT(10 20)'");
                var service = this.serviceFactory.CreateService();

                Action processUri = () => RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);
                processUri.ShouldThrow <DataServiceException>().WithMessage(Microsoft.OData.Core.Strings.MetadataBinder_IncompatibleOperandsError("Edm.Geography", "Edm.GeographyPoint", test.ErrorName));
            }
        }
示例#26
0
        /// <summary>
        /// Sets a resource reference to resource referenced by a URL.
        /// </summary>
        /// <param name="entityResource">The entity resource to set the resource reference on.</param>
        /// <param name="navigationProperty">The navigation property for which to set the reference to null.</param>
        /// <param name="url">The URL which points to the resource to set as the value of the navigation property.</param>
        private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url)
        {
            Debug.Assert(entityResource != null, "entityResource != null");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            // Update the object count when you are performing a bind operation.
            this.CheckAndIncrementObjectCount();

            // Get the referenced resource.
            Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(url, this.Service.OperationContext);
            RequestDescription requestDescription = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true /*internalQuery*/);

            // ATOM deserializer checks that the url doesn't point to a collection. If it does it will ignore the link.
            if (this.IsAtomRequest && !requestDescription.IsSingleResult)
            {
                if (navigationProperty != null &&
                    navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
                {
                    throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name));
                }

                return;
            }

            // Get the resource
            object referencedResource = this.Service.GetResource(requestDescription, requestDescription.SegmentInfos.Count - 1, null);

            if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
            {
                this.Updatable.SetReference(entityResource, navigationProperty.Name, referencedResource);
            }
            else
            {
                Debug.Assert(navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference, "Only navigation properties are allowed in this method.");

                // If we are to set the resource to a collection property it must not be null (so check for nulls), otherwise do allow nulls for backward compatibility.
                WebUtil.CheckResourceExists(referencedResource != null, requestDescription.LastSegmentInfo.Identifier);
                this.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, referencedResource);
            }
        }
示例#27
0
        /// <summary>
        /// Creates the navigation link for the given navigation property.
        /// </summary>
        /// <param name="entityToSerialize">Entity that is currently being serialized.</param>
        /// <param name="navigationProperty">The metadata for the navigation property.</param>
        /// <returns>The navigation link for the given property.</returns>
        private ODataNavigationLink GetNavigationLink(EntityToSerialize entityToSerialize, ResourceProperty navigationProperty)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            string navLinkName          = navigationProperty.Name;
            ODataNavigationLink navLink = new ODataNavigationLink
            {
                Name         = navLinkName,
                IsCollection = navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference
            };

            // Always pass the relative uri to the ODatalib. For Json, they will convert the relative uri
            // into absolute uri using the BaseUri property on the ODataWriterSettings. For atom, ODataLib
            // will write the relative uri.
            this.PayloadMetadataPropertyManager.SetUrl(navLink, () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLinkName));

            if (this.Service.Configuration.DataServiceBehavior.IncludeAssociationLinksInResponse)
            {
                this.PayloadMetadataPropertyManager.SetAssociationLinkUrl(navLink, () => GetAssociationLinkUrl(entityToSerialize, navigationProperty));
            }

            return(navLink);
        }
示例#28
0
        private void WriteNavigationProperties(IExpandedResult expanded, EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, IEnumerable <ProjectionNode> projectionNodesForCurrentResourceType)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(
                projectionNodesForCurrentResourceType == null ||
                projectionNodesForCurrentResourceType.All(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(entityToSerialize.ResourceType)),
                "The projection nodes must be filtered to the current resource type only.");

            IEnumerable <ResourceProperty> navProperties =
                projectionNodesForCurrentResourceType == null
                ? this.Provider.GetResourceSerializableProperties(this.CurrentContainer, entityToSerialize.ResourceType).Where(p => p.TypeKind == ResourceTypeKind.EntityType)
                : projectionNodesForCurrentResourceType.Where(p => p.Property != null && p.Property.TypeKind == ResourceTypeKind.EntityType).Select(p1 => p1.Property);

            foreach (ResourceProperty property in navProperties)
            {
                ResourcePropertyInfo navProperty = this.GetNavigationPropertyInfo(expanded, entityToSerialize.Entity, entityToSerialize.ResourceType, property);
                ODataNavigationLink  navLink     = this.GetNavigationLink(entityToSerialize, navProperty.Property);

                // WCF Data Services show performance degradation with JsonLight when entities have > 25 Navgations on writing entries
                // DEVNOTE: for performance reasons, if the link has no content due to the metadata level, and is not expanded
                // then don't tell ODataLib about it at all.
                if (navLink.Url == null && navLink.AssociationLinkUrl == null && !navProperty.Expand)
                {
                    continue;
                }

                var linkArgs = new DataServiceODataWriterNavigationLinkArgs(navLink, this.Service.OperationContext);
                this.dataServicesODataWriter.WriteStart(linkArgs);

                if (navProperty.Expand)
                {
                    object          navPropertyValue          = navProperty.Value;
                    IExpandedResult navPropertyExpandedResult = navPropertyValue as IExpandedResult;
                    object          expandedPropertyValue     =
                        navPropertyExpandedResult != null?
                        GetExpandedElement(navPropertyExpandedResult) :
                            navPropertyValue;

                    bool needPop = this.PushSegmentForProperty(navProperty.Property, entityToSerialize.ResourceType, navProperty.ExpandedNode);

                    // if this.CurrentContainer is null, the target set of the navigation property is hidden.
                    if (this.CurrentContainer != null)
                    {
                        if (navProperty.Property.Kind == ResourcePropertyKind.ResourceSetReference)
                        {
                            IEnumerable enumerable;
                            bool        collection = WebUtil.IsElementIEnumerable(expandedPropertyValue, out enumerable);
                            Debug.Assert(collection, "metadata loading must have ensured that navigation set properties must implement IEnumerable");

                            QueryResultInfo queryResults = new QueryResultInfo(enumerable);
                            try
                            {
                                queryResults.MoveNext();
                                Func <Uri> getNavPropertyRelativeUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLink.Name);
                                Func <Uri> getNavPropertyAbsoluteUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, navLink.Name);
                                this.WriteFeedElements(navPropertyExpandedResult, queryResults, navProperty.Property.ResourceType, navLink.Name, getNavPropertyRelativeUri, getNavPropertyAbsoluteUri, false);
                            }
                            finally
                            {
                                // After the navigation property is completely serialized, dispose the property value.
                                WebUtil.Dispose(queryResults);
                            }
                        }
                        else if (WebUtil.IsNullValue(expandedPropertyValue))
                        {
                            // Write a null reference navigation property
                            var entryArgs = new DataServiceODataWriterEntryArgs(null, null, this.Service.OperationContext);
                            this.dataServicesODataWriter.WriteStart(entryArgs);
                            this.dataServicesODataWriter.WriteEnd(entryArgs);
                        }
                        else
                        {
                            this.WriteEntry(navPropertyExpandedResult, expandedPropertyValue, resourceInstanceInFeed, navProperty.Property.ResourceType);
                        }
                    }

                    this.PopSegmentName(needPop);
                }

                this.dataServicesODataWriter.WriteEnd(linkArgs); // end of navigation property
            }
        }
示例#29
0
        /// <summary>
        /// Gets the association link URL.
        /// </summary>
        /// <param name="entityToSerialize">The entity to serialize.</param>
        /// <param name="navigationProperty">The navigation property.</param>
        /// <returns>The association link url.</returns>
        private static Uri GetAssociationLinkUrl(EntityToSerialize entityToSerialize, ResourceProperty navigationProperty)
        {
            Uri associationLinkUri = RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navigationProperty.Name);

            return(RequestUriProcessor.AppendEscapedSegment(associationLinkUri, XmlConstants.UriLinkSegment));
        }
示例#30
0
 /// <summary>
 /// Wraps a lazy URI with another that will have the given string appended if it is not null.
 /// </summary>
 /// <param name="lazyUri">The lazy URI to wrap.</param>
 /// <param name="suffix">The suffix for the URI.</param>
 /// <returns>A new lazy URI which will have the suffix, or the same instance if the suffix was null.</returns>
 private static SimpleLazy <Uri> AppendLazilyIfNeeded(SimpleLazy <Uri> lazyUri, string suffix)
 {
     return(suffix == null ? lazyUri : new SimpleLazy <Uri>(() => RequestUriProcessor.AppendUnescapedSegment(lazyUri.Value, suffix), false));
 }