/// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention, 
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <param name="odataUri">The OData Uri.</param>
 /// <returns>The created metadata builder.</returns>
 internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry, 
     IODataFeedAndEntryTypeContext typeContext, 
     ODataFeedAndEntrySerializationInfo serializationInfo, 
     IEdmEntityType actualEntityType, 
     SelectedPropertiesNode selectedProperties, 
     bool isResponse, 
     bool? keyAsSegment,
     ODataUri odataUri)
 {
     return ODataEntityMetadataBuilder.Null;
 }
        public void BuildUrlWithNewODataUri()
        {
            ODataUri uri = new ODataUri();
            uri.ServiceRoot = new Uri("http://gobbledygook/");
            uri.Skip = 4;
            uri.Top = 5;
            uri.Path = new ODataPath(new EntitySetSegment(HardCodedTestModel.GetPeopleSet()));
            Assert.Equal(uri.ParameterAliasNodes.Count, 0);

            ODataUriBuilder builder = new ODataUriBuilder(ODataUrlConventions.Default, uri);
            Uri res = builder.BuildUri();
            Assert.Equal(new Uri("http://gobbledygook/People?$top=5&$skip=4"), res);
        }
 /// <summary>
 /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
 /// metadata properties (like EditLink) of the entry may return a value computed by convention, 
 /// depending on the metadata level and whether the user manually set an edit link or not.
 /// </summary>
 /// <param name="entry">The entry to create the metadata builder for.</param>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
 /// <param name="serializationInfo">The serialization info for the entry.</param>
 /// <param name="actualEntityType">The entity type of the entry.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
 /// <param name="keyAsSegment">true if keys should go in separate segments in auto-generated URIs, false if they should go in parentheses.
 /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
 /// <param name="odataUri">The OData Uri.</param>
 /// <returns>The created metadata builder.</returns>
 internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
     ODataEntry entry, 
     IODataFeedAndEntryTypeContext typeContext, 
     ODataFeedAndEntrySerializationInfo serializationInfo, 
     IEdmEntityType actualEntityType, 
     SelectedPropertiesNode selectedProperties, 
     bool isResponse, 
     bool? keyAsSegment,
     ODataUri odataUri)
 {
     // For minimal metadata we don't want to change the metadata builder that's currently on the entry because the entry might come from a JSON light
     // reader and it would contain the metadata builder from the reader.  Until we give the user the ability to choose whether to write what was reported
     // by the reader versus what was on the wire, we no-op here so the writer will just write what's on the OM for now.
     return null;
 }
 public void BuildPathWithFunctionImport()
 {
     ODataUri odataUri = new ODataUri();
     odataUri.ServiceRoot = new Uri("http://gobbledygook/");
     IEdmOperationImport functionImport = HardCodedTestModel.TestModel.EntityContainer.FindOperationImports("GetPet1").Single();
     IEdmEntitySetReferenceExpression reference = functionImport.EntitySet as IEdmEntitySetReferenceExpression;
     OperationSegmentParameter[] parameters = new OperationSegmentParameter[] { new OperationSegmentParameter("id", new ConstantNode(1, "1")) };
     odataUri.Path = new ODataPath(new OperationImportSegment(
         new IEdmOperationImport[] { functionImport },
         reference.ReferencedEntitySet,
         parameters));
     ODataUriBuilder odataUriBuilder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
     Uri actual = odataUriBuilder.BuildUri();
     Assert.Equal(new Uri("http://gobbledygook/GetPet1(id=1)"), actual);
 }
Esempio n. 5
0
        public void BuildPath_AliasInFunctionImport()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/GetPet4(id=@p1)?@p1=1.01M");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Path.LastSegment.ShouldBeOperationImportSegment(HardCodedTestModel.GetFunctionImportForGetPet4()).And.Parameters.First().ShouldHaveParameterAliasNode("id", "@p1", EdmCoreModel.Instance.GetDecimal(false));
            aliasNodes["@p1"].ShouldBeConstantQueryNode(1.01M);

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 6
0
        public void BuildFilter_AliasInFunction_PropertyAsValue()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$filter=Fully.Qualified.Namespace.HasDog(inOffice%3Dfalse%2Cname%3D%40p1)&@p1=Name");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Filter.Expression.ShouldBeSingleValueFunctionCallQueryNode(HardCodedTestModel.GetHasDogOverloadForPeopleWithThreeParameters().As <IEdmFunction>()).And.Parameters.Last().As <NamedFunctionParameterNode>().Value.ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetString(true));
            aliasNodes["@p1"].ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPeopleSet().EntityType().FindProperty("Name"));

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 7
0
        public void BuildFilter_AliasInFunction()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$filter=Fully.Qualified.Namespace.AllHaveDog(inOffice%3D%40p1)&@p1=true");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Filter.Expression.ShouldBeSingleValueFunctionCallQueryNode(HardCodedTestModel.GetFunctionForAllHaveDogWithTwoParameters()).And.Parameters.Last().As <NamedFunctionParameterNode>().Value.ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetBoolean(false));
            aliasNodes["@p1"].ShouldBeConstantQueryNode(true);

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 8
0
        public async Task NavigationNextPageLink()
        {
            String request = "Orders?$expand=Items($filter=Count gt 0 or Count eq null;$orderby=Id;$count=true)&$orderby=Id&$count=true";

            ODataUri  odataUri   = Fixture.ParseUri(request);
            IEdmModel edmModel   = Fixture.OeEdmModel.GetEdmModel(odataUri.Path);
            var       requestUri = new Uri(odataUri.ServiceRoot, request);

            var expectedResponse = new MemoryStream();
            var expectedParser   = new OeParser(odataUri.ServiceRoot, edmModel);
            await expectedParser.ExecuteGetAsync(requestUri, OeRequestHeaders.JsonDefault, expectedResponse, CancellationToken.None).ConfigureAwait(false);

            expectedResponse.Position = 0;

            var           exprectedReader = new ResponseReader(edmModel);
            List <Object> expectedResult  = exprectedReader.Read(expectedResponse).Cast <Object>().ToList();

            List <Object> fromOe = await OrdersCountItemsCount(Fixture, request, i => i.Count == null || i.Count > 0, 1, true);

            TestHelper.Compare(expectedResult, fromOe, null);
        }
        public void WriteContainedEntitySet()
        {
            EdmModel model = new EdmModel();
            EdmEntityType entityType = GetEntityType();
            model.AddElement(entityType);
            IEdmNavigationSource containedEntitySet = GetContainedEntitySet(model, entityType);
            var requestUri = new Uri("http://temp.org/FakeSet('parent')/nav");
            var odataUri = new ODataUri { RequestUri = requestUri };
            odataUri.Path = new ODataUriParser(model, new Uri("http://temp.org/"), requestUri).ParsePath();

            ODataEntry entry = new ODataEntry() { Properties = new[] { new ODataProperty { Name = "Key", Value = "son" }, } };
            var actual = WriteJsonLightEntry(
                isRequest: false,
                serviceDocumentUri: new Uri("http://temp.org/"),
                specifySet: true,
                odataEntry: entry,
                entitySet: containedEntitySet,
                entityType: containedEntitySet.Type as IEdmEntityType,
                odataUri: odataUri);
            actual.Should().Contain("\"@odata.id\":\"FakeSet('parent')/nav('son')\"");
        }
        public void BuildOrderby_AliasInBinaryOp()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$orderby=ID%20mul%20%40p1%20asc&@p1=3 div 2");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.OrderBy.Expression.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Multiply).Right.ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetInt32(false));
            aliasNodes["@p1"].ShouldBeBinaryOperatorNode(BinaryOperatorKind.Divide).Right.ShouldBeConstantQueryNode(2);

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(new Uri("http://gobbledygook/People?$orderby=ID%20mul%20%40p1&@p1=3 div 2"), actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(new Uri("http://gobbledygook/People?$orderby=ID%20mul%20%40p1&@p1=3 div 2"), actualUri);
        }
        public void BuildFilter_AliasInFunction_BuiltIn()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$filter=contains(%40p1%2CName)&@p1=Name");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            Assert.IsType <SingleValueFunctionCallNode>(odataUri.Filter.Expression).Parameters.First().ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetString(true));
            aliasNodes["@p1"].ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPeopleSet().EntityType().FindProperty("Name"));

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 12
0
        protected OeAsyncEnumerator GetAsyncEnumerator(HttpContext httpContext, Stream responseStream, bool navigationNextLink = false, int?maxPageSize = null)
        {
            String controllerName = base.ControllerContext.ActionDescriptor.ControllerName;
            var    odataParser    = new ODataUriParser(_edmModel, UriHelper.GetBaseUri(httpContext.Request, controllerName), UriHelper.GetUri(httpContext.Request));

            odataParser.Resolver.EnableCaseInsensitive = true;
            ODataUri odataUri = odataParser.ParseUri();

            var requestHeaders       = (HttpRequestHeaders)httpContext.Request.Headers;
            OeRequestHeaders headers = GetRequestHeaders(requestHeaders, httpContext.Response, navigationNextLink, maxPageSize);

            if (odataUri.Path.LastSegment is OperationImportSegment)
            {
                return(Execute(odataUri, httpContext.Request.Body, headers, httpContext.RequestAborted));
            }

            var getParser = new OeGetParser(_dataAdapter, _edmModel);

            _queryContext = getParser.CreateQueryContext(odataUri, headers.MaxPageSize, headers.NavigationNextLink, headers.MetadataLevel);
            return(Execute(headers, responseStream, httpContext.RequestAborted));
        }
Esempio n. 13
0
        public async Task ExecutePostAsync(Uri requestUri, OeRequestHeaders headers, Stream requestStream, Stream responseStream, CancellationToken cancellationToken)
        {
            var odataParser = new ODataUriParser(_edmModel, _baseUri, requestUri);

            odataParser.Resolver.EnableCaseInsensitive = true;
            ODataUri odataUri = odataParser.ParseUri();

            if (odataUri.Path.LastSegment.Identifier == "$batch")
            {
                await ExecuteBatchAsync(responseStream, responseStream, headers.ContentType, cancellationToken).ConfigureAwait(false);
            }
            else
            if (odataUri.Path.LastSegment is OperationImportSegment)
            {
                await ExecuteOperationAsync(odataUri, headers, requestStream, responseStream, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                await ExecuteQueryAsync(odataUri, headers, responseStream, cancellationToken).ConfigureAwait(false);
            }
        }
Esempio n. 14
0
        public void BuildFilter_AliasInBinaryOp_ValueAsExpression()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$filter=ID%20eq%20%40p1&@p1=1 add 2");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Filter.Expression.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Equal).And.Right.ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetInt32(false));
            aliasNodes["@p1"].ShouldBeBinaryOperatorNode(BinaryOperatorKind.Add).And.Right.ShouldBeConstantQueryNode(2);

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 15
0
        public void BuildPath_AliasInBoundFunction()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People(123)/Fully.Qualified.Namespace.HasHat(onCat=@p1)?@p1=true");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Path.LastSegment.ShouldBeOperationSegment(HardCodedTestModel.TestModel.FindOperations("Fully.Qualified.Namespace.HasHat").Single(s => (s as IEdmFunction).Parameters.Count() == 2)).As <IEdmFunction>();
            aliasNodes["@p1"].ShouldBeConstantQueryNode(true);

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.NotEqual(fullUri, actualUri);
        }
Esempio n. 16
0
        internal OeQueryContext(IEdmModel edmModel, ODataUri odataUri,
                                IEdmEntitySet entitySet, IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments,
                                bool isCountSegment, int pageSize, bool navigationNextLink, bool isDatabaseNullHighestValue,
                                OeMetadataLevel metadataLevel, Db.OeEntitySetAdapter entitySetAdapter)
        {
            EntitySetAdapter           = entitySetAdapter;
            EdmModel                   = edmModel;
            ODataUri                   = odataUri;
            EntitySet                  = entitySet;
            ParseNavigationSegments    = parseNavigationSegments;
            IsCountSegment             = isCountSegment;
            PageSize                   = pageSize;
            NavigationNextLink         = navigationNextLink;
            IsDatabaseNullHighestValue = isDatabaseNullHighestValue;
            MetadataLevel              = metadataLevel;

            if (pageSize > 0 || (odataUri.OrderBy != null && odataUri.Skip != null && odataUri.Top != null))
            {
                SkipTokenNameValues = OeSkipTokenParser.CreateNameValues(edmModel, odataUri.OrderBy, odataUri.SkipToken);
            }
        }
        internal OeQueryContext(IEdmModel edmModel, ODataUri odataUri,
                                IEdmEntitySet entitySet, IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments,
                                bool isCountSegment, int pageSize, bool navigationNextLink, bool isDatabaseNullHighestValue,
                                OeMetadataLevel metadataLevel, ref Db.OeEntitySetAdapter entitySetAdapter)
        {
            EntitySetAdapter        = entitySetAdapter;
            EdmModel                = edmModel;
            ODataUri                = odataUri;
            EntitySet               = entitySet;
            ParseNavigationSegments = parseNavigationSegments;
            IsCountSegment          = isCountSegment;
            PageSize                = pageSize;
            NavigationNextLink      = navigationNextLink;
            MetadataLevel           = metadataLevel;

            if (pageSize > 0 || (odataUri.OrderBy != null && odataUri.Skip != null && odataUri.Top != null))
            {
                IEdmEntityType edmEntityType = OeGetParser.GetEntityType(odataUri.Path, parseNavigationSegments);
                SkipTokenParser = new OeSkipTokenParser(edmModel, edmEntityType, isDatabaseNullHighestValue, odataUri.OrderBy);
            }
        }
Esempio n. 18
0
        private static Uri GenerateQueryFromExpandedItem(ODataSerializerContext writeContext, Uri navigationLink)
        {
            string         serviceRoot    = writeContext.Request.CreateODataLink(new List <ODataPathSegment>());
            Uri            serviceRootUri = new Uri(serviceRoot);
            ODataUriParser parser         = new ODataUriParser(writeContext.Model, serviceRootUri, navigationLink);
            ODataUri       newUri         = parser.ParseUri();

            newUri.SelectAndExpand = writeContext.SelectExpandClause;
            if (writeContext.CurrentExpandedSelectItem != null)
            {
                newUri.OrderBy = writeContext.CurrentExpandedSelectItem.OrderByOption;
                newUri.Filter  = writeContext.CurrentExpandedSelectItem.FilterOption;
                newUri.Skip    = writeContext.CurrentExpandedSelectItem.SkipOption;
                newUri.Top     = writeContext.CurrentExpandedSelectItem.TopOption;

                if (writeContext.CurrentExpandedSelectItem.CountOption != null)
                {
                    if (writeContext.CurrentExpandedSelectItem.CountOption.HasValue)
                    {
                        newUri.QueryCount = writeContext.CurrentExpandedSelectItem.CountOption.Value;
                    }
                }

                ExpandedNavigationSelectItem expandedNavigationItem = writeContext.CurrentExpandedSelectItem as ExpandedNavigationSelectItem;
                if (expandedNavigationItem != null)
                {
                    newUri.SelectAndExpand = expandedNavigationItem.SelectAndExpand;
                }
            }

            ODataUrlKeyDelimiter keyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataOptions         options      = writeContext.Request.HttpContext.RequestServices.GetRequiredService <IOptions <ODataOptions> >().Value;

            if (options != null)
            {
                keyDelimiter = options.UrlKeyDelimiter;
            }

            return(newUri.BuildUri(keyDelimiter));
        }
Esempio n. 19
0
        public async Task NextPageLink()
        {
            String request = "OrderItems?$orderby=Id&$count=true";

            ODataUri         odataUri       = Fixture.ParseUri(request);
            IEdmModel        edmModel       = Fixture.EdmModel.GetEdmModel(odataUri.Path);
            var              parser         = new OeParser(odataUri.ServiceRoot, edmModel);
            var              uri            = new Uri(odataUri.ServiceRoot, request);
            OeRequestHeaders requestHeaders = OeRequestHeaders.JsonDefault.SetMaxPageSize(2);

            long count  = -1;
            var  fromOe = new List <Object>();

            do
            {
                var response = new MemoryStream();
                await parser.ExecuteGetAsync(uri, requestHeaders, response, CancellationToken.None).ConfigureAwait(false);

                var reader = new ResponseReader(edmModel);
                response.Position = 0;

                List <Object> result = reader.Read(response).Cast <Object>().ToList();
                Assert.InRange(result.Count, 0, requestHeaders.MaxPageSize);
                fromOe.AddRange(result);

                if (count < 0)
                {
                    count = reader.ResourceSet.Count.GetValueOrDefault();
                }
                uri = reader.ResourceSet.NextPageLink;
            }while (uri != null);
            Assert.Equal(count, fromOe.Count);

            IList fromDb;

            using (var context = Fixture.CreateContext())
                fromDb = context.OrderItems.OrderBy(i => i.Id).ToList();

            TestHelper.Compare(fromDb, fromOe, Fixture.MetadataProvider, null);
        }
        private Uri GetNavigationUri(OeEntryFactory entryFactory, ExpandedNavigationSelectItem item, OrderByClause orderByClause, Object value, String skipToken)
        {
            bool?queryCount = item.CountOption;
            long?top        = item.TopOption;

            if (skipToken != null)
            {
                queryCount = null;
                int pageSize = item.GetPageSize();
                if (pageSize > 0 && (top == null || pageSize < top.GetValueOrDefault()))
                {
                    top = pageSize;
                }
            }

            FilterClause filterClause = GetFilter(_queryContext.EdmModel, entryFactory, item, value);

            if (filterClause == null)
            {
                return(null);
            }

            var entitytSet   = (IEdmEntitySet)(filterClause.RangeVariable as ResourceRangeVariable).NavigationSource;
            var pathSegments = new ODataPathSegment[] { new EntitySetSegment(entitytSet) };

            var odataUri = new ODataUri()
            {
                Filter          = filterClause,
                OrderBy         = orderByClause,
                Path            = new ODataPath(pathSegments),
                QueryCount      = queryCount,
                SelectAndExpand = item.SelectAndExpand,
                Skip            = item.SkipOption,
                SkipToken       = skipToken,
                Top             = top
            };

            return(odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses));
        }
Esempio n. 21
0
        internal OeQueryContext(IEdmModel edmModel, ODataUri odataUri,
                                IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments,
                                bool isCountSegment, int pageSize, bool navigationNextLink, OeMetadataLevel metadataLevel, Db.OeEntitySetAdapter entitySetAdapter)
        {
            EntitySetAdapter        = entitySetAdapter;
            EdmModel                = edmModel;
            ODataUri                = odataUri;
            ParseNavigationSegments = parseNavigationSegments;
            IsCountSegment          = isCountSegment;
            PageSize                = pageSize;
            NavigationNextLink      = navigationNextLink;
            MetadataLevel           = metadataLevel;

            var visitor = new OeQueryNodeVisitor(edmModel, Expression.Parameter(entitySetAdapter.EntityType));

            JoinBuilder = new Translators.OeJoinBuilder(visitor);

            if (pageSize > 0 || (odataUri.OrderBy != null && odataUri.Skip != null && odataUri.Top != null))
            {
                SkipTokenNameValues = OeSkipTokenParser.CreateNameValues(edmModel, odataUri.OrderBy, odataUri.SkipToken);
            }
        }
        /// <summary>
        /// Returns the strategy to use for serializing/deserialzing the given content type
        /// </summary>
        /// <param name="contentType">The content type</param>
        /// <param name="uri">The request uri</param>
        /// <returns>A serialization strategy</returns>
        public virtual IProtocolFormatStrategy GetStrategy(string contentType, ODataUri uri)
        {
            if (uri != null)
            {
                // if its a named stream or an MLE, handle the returned payload as a binary stream
                if (uri.IsNamedStream() || uri.IsMediaResource())
                {
                    return(this.BinaryValueStrategy);
                }

                // if its a raw $count request, we need to use a different strategy
                if (uri.IsCount() && IsPlainTextMimeType(contentType))
                {
                    return(this.CountStrategy);
                }
            }

            if (IsXmlMimeType(contentType))
            {
                return(this.XmlStrategy);
            }

            if (IsJsonMimeType(contentType))
            {
                return(this.JsonStrategy);
            }

            if (IsTextBasedMimeType(contentType))
            {
                return(this.TextValueStrategy);
            }

            if (IsHtmlFormMimeType(contentType))
            {
                return(this.HtmlFormStrategy);
            }

            return(this.BinaryValueStrategy);
        }
Esempio n. 23
0
        public void BuildOrderby_AliasInFunction()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$orderby=Fully.Qualified.Namespace.HasDog(inOffice%3D%40p1)&@p1=true");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;
            var expectedFunc = HardCodedTestModel.GetAllHasDogFunctionOverloadsForPeople().Single(s => s.Parameters.Count() == 2);

            odataUri.OrderBy.Expression.ShouldBeSingleValueFunctionCallQueryNode(expectedFunc).And.Parameters.Last().As <NamedFunctionParameterNode>().Value.ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetBoolean(false));
            aliasNodes["@p1"].ShouldBeConstantQueryNode(true);

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 24
0
        /// <summary>
        /// Parse a full Uri into its contingent parts with semantic meaning attached to each part.
        /// See <see cref="ODataUri"/>.
        /// </summary>
        /// <returns>An <see cref="ODataUri"/> representing the full uri.</returns>
        public ODataUri ParseUri()
        {
            ExceptionUtils.CheckArgumentNotNull(this.configuration.Model, "model");
            ExceptionUtils.CheckArgumentNotNull(this.fullUri, "fullUri");

            ODataPath          path         = this.ParsePath();
            SelectExpandClause selectExpand = this.ParseSelectAndExpand();
            FilterClause       filter       = this.ParseFilter();
            OrderByClause      orderBy      = this.ParseOrderBy();
            SearchClause       search       = this.ParseSearch();
            long?top   = this.ParseTop();
            long?skip  = this.ParseSkip();
            bool?count = this.ParseCount();

            // TODO:  check it shouldn't be empty
            List <QueryNode> boundQueryOptions = new List <QueryNode>();

            ODataUri odataUri = new ODataUri(this.ParameterAliasValueAccessor, path, boundQueryOptions, selectExpand, filter, orderBy, search, skip, top, count);

            odataUri.ServiceRoot = this.serviceRoot;
            return(odataUri);
        }
Esempio n. 25
0
        public void BuildExpandOrderby_AliasInFunction()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$expand=MyPet2Set($orderby=concat(Color, @p1 )asc )&@p1='abc'");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;
            SingleValueFunctionCallNode           node       = (odataUri.SelectAndExpand.SelectedItems.First() as ExpandedNavigationSelectItem).OrderByOption.Expression as SingleValueFunctionCallNode;

            node.Parameters.Last().ShouldBeParameterAliasNode("@p1", EdmCoreModel.Instance.GetString(true));
            aliasNodes["@p1"].ShouldBeConstantQueryNode("abc");

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal("http://gobbledygook/People?$expand=" + Uri.EscapeDataString("MyPet2Set($orderby=concat(Color,@p1))") + "&@p1=" + Uri.EscapeDataString("'abc'"), actualUri.OriginalString);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal("http://gobbledygook/People?$expand=" + Uri.EscapeDataString("MyPet2Set($orderby=concat(Color,@p1))") + "&@p1=" + Uri.EscapeDataString("'abc'"), actualUri.OriginalString);
        }
Esempio n. 26
0
        public void BuildFilter_AliasInFunction_WithoutValue()
        {
            Uri            fullUri        = new Uri("http://gobbledygook/People?$filter=Fully.Qualified.Namespace.HasDog(inOffice%3D%40p1%2Cname%3D%40p2)");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);

            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary <string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Filter.Expression.ShouldBeSingleValueFunctionCallQueryNode(HardCodedTestModel.GetHasDogOverloadForPeopleWithThreeParameters().As <IEdmFunction>()).And.Parameters.Last().As <NamedFunctionParameterNode>().Value.ShouldBeParameterAliasNode("@p2", null);
            aliasNodes["@p1"].Should().BeNull();
            aliasNodes["@p2"].Should().BeNull();

            Uri actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(fullUri, actualUri);

            actualUri = odataUri.BuildUri(ODataUrlKeyDelimiter.Slash);
            Assert.Equal(fullUri, actualUri);
        }
Esempio n. 27
0
        public async Task ExecuteAsync(ODataUri odataUri, OeRequestHeaders headers, Stream stream, CancellationToken cancellationToken)
        {
            OeQueryContext queryContext = CreateQueryContext(odataUri, headers.MaxPageSize, headers.NavigationNextLink, headers.MetadataLevel);

            if (queryContext.ODataUri.Path.LastSegment is OperationSegment)
            {
                using (Db.OeAsyncEnumerator asyncEnumerator = OeOperationHelper.ApplyBoundFunction(queryContext))
                    await Writers.OeGetWriter.SerializeAsync(queryContext, asyncEnumerator, headers.ContentType, stream).ConfigureAwait(false);

                return;
            }

            Object dataContext = null;

            Db.OeDataAdapter dataAdapter = queryContext.EdmModel.GetDataAdapter(queryContext.EdmModel.EntityContainer);
            try
            {
                dataContext = dataAdapter.CreateDataContext();
                if (queryContext.IsCountSegment)
                {
                    headers.ResponseContentType = OeRequestHeaders.TextDefault.ContentType;
                    int    count  = dataAdapter.ExecuteScalar <int>(dataContext, queryContext);
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(count.ToString(CultureInfo.InvariantCulture));
                    stream.Write(buffer, 0, buffer.Length);
                }
                else
                {
                    using (Db.OeAsyncEnumerator asyncEnumerator = dataAdapter.ExecuteEnumerator(dataContext, queryContext, cancellationToken))
                        await Writers.OeGetWriter.SerializeAsync(queryContext, asyncEnumerator, headers.ContentType, stream).ConfigureAwait(false);
                }
            }
            finally
            {
                if (dataContext != null)
                {
                    dataAdapter.CloseDataContext(dataContext);
                }
            }
        }
Esempio n. 28
0
        /// <summary>
        /// Compute id for containment scenario.
        /// </summary>
        /// <returns>
        /// The <see cref="Uri"/> of @odata.id.
        /// </returns>
        private Uri ComputeIdForContainment()
        {
            Uri uri;

            if (!TryComputeIdFromParent(out uri))
            {
                // Compute ID from context URL rather than from parent.
                uri = this.UriBuilder.BuildBaseUri();
                ODataUri odataUri = this.ODataUri ?? this.MetadataContext.ODataUri;

                if (odataUri == null || odataUri.Path == null || odataUri.Path.Count == 0)
                {
                    throw new ODataException(Strings.ODataMetadataBuilder_MissingParentIdOrContextUrl);
                }

                uri = this.GetContainingEntitySetUri(uri, odataUri);
            }

            // A path segment for the containment navigation property
            uri = this.UriBuilder.BuildEntitySetUri(uri, this.ResourceMetadataContext.TypeContext.NavigationSourceName);

            if (this.ResourceMetadataContext.TypeContext.IsFromCollection)
            {
                if (this.ResourceMetadataContext.KeyProperties.Any())
                {
                    uri = this.UriBuilder.BuildEntityInstanceUri(
                        uri,
                        this.ComputedKeyProperties,
                        this.ResourceMetadataContext.ActualResourceTypeName);
                }
                else
                {
                    uri = null;
                }
            }

            return(uri);
        }
Esempio n. 29
0
        private static void BuildOrderBy()
        {
            var productTypeRef   = new EdmEntityTypeReference(V4Model.Product, false);
            var supplierProperty = (IEdmNavigationProperty)V4Model.Product.FindProperty("Supplier");
            var nameProperty     = V4Model.Supplier.FindProperty("Name");

            var topIt           = new EntityRangeVariable("$it", productTypeRef, V4Model.ProductsSet);
            var topItRef        = new EntityRangeVariableReferenceNode("$it", topIt);
            var supplierNavNode = new SingleNavigationNode(supplierProperty, topItRef);
            var nameNode        = new SingleValuePropertyAccessNode(supplierNavNode, nameProperty);

            var orderby  = new OrderByClause(null, nameNode, OrderByDirection.Ascending, topIt);
            var odataUri = new ODataUri
            {
                Path        = new ODataPath(new EntitySetSegment(V4Model.ProductsSet)),
                ServiceRoot = V4Root,
                OrderBy     = orderby
            };
            var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);

            Console.WriteLine(builder.BuildUri());
            // http://services.odata.org/V4/OData/OData.svc/Products?$orderby=Supplier%2FName
        }
Esempio n. 30
0
        /// <summary>
        /// Determines whether the request manager should try to resolve the payload's metadata
        /// </summary>
        /// <param name="requestUri">The request uri</param>
        /// <param name="responseStatusCode">The response status code</param>
        /// <param name="responsePayloadType">The response payload type</param>
        /// <returns>True if it should resolve the metadata, false otherwise</returns>
        internal static bool ShouldResolveMetadata(ODataUri requestUri, HttpStatusCode responseStatusCode, ODataPayloadElementType responsePayloadType)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestUri, "requestUri");

            if (responseStatusCode.IsError())
            {
                return(false);
            }

            if (requestUri.IsNamedStream() || requestUri.IsMediaResource())
            {
                return(false);
            }

            if (responsePayloadType == ODataPayloadElementType.MetadataPayloadElement ||
                responsePayloadType == ODataPayloadElementType.HtmlErrorPayload ||
                responsePayloadType == ODataPayloadElementType.ODataErrorPayload)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 31
0
        public async Task CountQueryParameterFilter()
        {
            String request = "OrderItems?$filter=OrderId eq 1&$count=true&$top=1";

            ODataUri odataUri = Fixture.ParseUri(request);
            var      parser   = new OeParser(odataUri.ServiceRoot, Fixture.OeDataAdapter, Fixture.EdmModel);

            var response = new MemoryStream();
            await parser.ExecuteQueryAsync(odataUri, OeRequestHeaders.JsonDefault, response, CancellationToken.None).ConfigureAwait(false);

            response.Position = 0;

            var reader = new ResponseReader(Fixture.EdmModel, Fixture.OeDataAdapter.EntitySetMetaAdapters);

            reader.Read(response).Cast <Object>().Single();

            int?expectedCount;

            using (var dbContext = Fixture.CreateContext())
                expectedCount = dbContext.OrderItems.Count(i => i.OrderId == 1);

            Assert.Equal(expectedCount, reader.ResourceSet.Count);
        }
Esempio n. 32
0
        public async Task NavigationNextLink()
        {
            String request = "Categories?$expand=Children";

            OeParser parser   = Fixture.CreateParser(request, Fixture.ModelBoundProvider);
            ODataUri odataUri = Fixture.ParseUri(request);

            var response = new MemoryStream();
            await parser.ExecuteQueryAsync(odataUri, OeRequestHeaders.JsonDefault, response, CancellationToken.None).ConfigureAwait(false);

            response.Position = 0;

            var           reader     = new ResponseReader(parser.EdmModel);
            List <Object> categories = reader.Read(response).Cast <Object>().ToList();

            foreach (dynamic category in categories)
            {
                ResponseReader.NavigationInfo navigationInfo = reader.GetNavigationInfo(category.Children);
                String actual   = Uri.UnescapeDataString(navigationInfo.NextPageLink.OriginalString);
                String expected = $"http://dummy/Categories?$filter=ParentId eq {category.Id}";
                Assert.Equal(expected, actual);
            }
        }
        /// <summary>
        /// Find out whether to expect action descriptor with projection in request uri
        /// </summary>
        /// <param name="requestUri">The request uri</param>
        /// <param name="action">The action</param>
        /// <param name="isTopLevelElement">Whether the entity being verified is top level payload element</param>
        /// <returns>Whether to expect action descriptor</returns>
        private bool ExpectActionWithProjection(ODataUri requestUri, Function action, bool isTopLevelElement)
        {
            ODataUriSegmentPathCollection selectSegments = requestUri.SelectSegments;
            ODataUriSegmentPathCollection expandSegments = requestUri.ExpandSegments;

            // handle single level $select path, expect action descriptor if $select=ActionName or $select=Container.*
            foreach (var selectSegmentPath in selectSegments.Where(ss => ss.Count == 1))
            {
                ODataUriSegment selectSegment = selectSegmentPath.Single();

                if (isTopLevelElement && this.FuctionMatchWithSelectFunctionSegment(action, selectSegment))
                {
                    return(true);
                }

                if (this.IsSelectAllFunctionSegment(selectSegment))
                {
                    return(true);
                }
            }

            // handle multiple level $select path, expect action descriptor for $expand=Rating if: $select=Rating or $select=Rating/ActionName or $Select=Rating/Container.*
            foreach (var expandSegmentPath in expandSegments)
            {
                List <ODataUriSegment> expandSegmentList = expandSegmentPath.ToList();
                foreach (var selectSegmentPath in selectSegments.Where(ss => ss.Count == expandSegmentPath.Count || ss.Count == expandSegmentPath.Count + 1))
                {
                    List <ODataUriSegment> selectSegmentList = selectSegmentPath.ToList();
                    if (this.FunctionMatchWithExpandSegmentList(selectSegmentList, expandSegmentList, action))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Esempio n. 34
0
        /// <summary>
        /// Creates the metadata builder for the given resource. If such a builder is set, asking for payload
        /// metadata properties (like EditLink) of the resource may return a value computed by convention,
        /// depending on the metadata level and whether the user manually set an edit link or not.
        /// </summary>
        /// <param name="resource">The resource to create the metadata builder for.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the resource or resource set.</param>
        /// <param name="serializationInfo">The serialization info for the resource.</param>
        /// <param name="actualResourceType">The structured type of the resource.</param>
        /// <param name="selectedProperties">The selected properties of this scope.</param>
        /// <param name="isResponse">true if the resource metadata builder to create should be for a response payload; false for a request.</param>
        /// <param name="keyAsSegment">true if keys should go in separate segments in auto-generated URIs, false if they should go in parentheses.</param>
        /// <param name="odataUri">The OData Uri.</param>
        /// <param name="settings">OData message writer settings.</param>
        /// <returns>The created metadata builder.</returns>
        internal override ODataResourceMetadataBuilder CreateResourceMetadataBuilder(
            ODataResourceBase resource,
            IODataResourceTypeContext typeContext,
            ODataResourceSerializationInfo serializationInfo,
            IEdmStructuredType actualResourceType,
            SelectedPropertiesNode selectedProperties,
            bool isResponse,
            bool keyAsSegment,
            ODataUri odataUri,
            ODataMessageWriterSettings settings)
        {
            Debug.Assert(resource != null, "resource != null");
            Debug.Assert(typeContext != null, "typeContext != null");
            Debug.Assert(selectedProperties != null, "selectedProperties != null");

            IODataMetadataContext metadataContext = new ODataMetadataContext(
                isResponse,
                this.model,
                this.NonNullMetadataDocumentUri,
                odataUri);

            ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri,
                                                                                     keyAsSegment ? ODataUrlKeyDelimiter.Slash : ODataUrlKeyDelimiter.Parentheses);

            IODataResourceMetadataContext resourceMetadataContext = ODataResourceMetadataContext.Create(resource, typeContext, serializationInfo, actualResourceType, metadataContext, selectedProperties, settings != null ? settings.MetadataSelector : null);

            // Create ODataConventionalEntityMetadataBuilder if actualResourceType is entity type or typeContext.NavigationSourceKind is not none (complex type would be none) for no model scenario.
            if (actualResourceType != null && actualResourceType.TypeKind == EdmTypeKind.Entity ||
                actualResourceType == null && typeContext.NavigationSourceKind != EdmNavigationSourceKind.None)
            {
                return(new ODataConventionalEntityMetadataBuilder(resourceMetadataContext, metadataContext, uriBuilder));
            }
            else
            {
                return(new ODataConventionalResourceMetadataBuilder(resourceMetadataContext, metadataContext, uriBuilder));
            }
        }
Esempio n. 35
0
        public void ExpandWithNestedQueryOptionsShouldWork()
        {
            var ervFilter  = new ResourceRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet());
            var ervOrderby = new ResourceRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet());
            var expand     =
                new ExpandedNavigationSelectItem(
                    new ODataExpandPath(new NavigationPropertySegment(HardCodedTestModel.GetPersonMyDogNavProp(), null)),
                    HardCodedTestModel.GetPeopleSet(),
                    null,
                    new FilterClause(
                        new BinaryOperatorNode(
                            BinaryOperatorKind.Equal,
                            new SingleValuePropertyAccessNode(new ResourceRangeVariableReferenceNode("$it", ervFilter), HardCodedTestModel.GetDogColorProp()),
                            new ConstantNode("Brown", "'Brown'")),
                        ervFilter),
                    new OrderByClause(
                        null,
                        new SingleValuePropertyAccessNode(new ResourceRangeVariableReferenceNode("$it", ervOrderby), HardCodedTestModel.GetDogColorProp()),
                        OrderByDirection.Ascending,
                        ervOrderby),
                    1,
                    /* skipOption */ null,
                    true,
                    new SearchClause(new SearchTermNode("termX")),
                    /* levelsOption*/ null);

            ODataUri uri = new ODataUri()
            {
                ServiceRoot     = new Uri("http://gobbledygook/"),
                Path            = new ODataPath(new EntitySetSegment(HardCodedTestModel.GetPeopleSet())),
                SelectAndExpand = new SelectExpandClause(new[] { expand }, true)
            };

            Uri actualUri = uri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal("http://gobbledygook/People?$expand=" + Uri.EscapeDataString("MyDog($filter=Color eq 'Brown';$orderby=Color;$top=1;$count=true;$search=termX)"), actualUri.OriginalString);
        }
            /// <summary>
            /// Constructor to create a new delta link scope.
            /// </summary>
            /// <param name="state">The writer state of this scope.</param>
            /// <param name="link">The link for the new scope.</param>
            /// <param name="serializationInfo">The serialization info for the current entry.</param>
            /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
            /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
            /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
            /// <param name="selectedProperties">The selected properties of this scope.</param>
            /// <param name="odataUri">The ODataUri info of this scope.</param>
            protected DeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
                : base(state, link, navigationSource, entityType, selectedProperties, odataUri)
            {
                Debug.Assert(link != null, "link != null");
                Debug.Assert(
                    state == WriterState.DeltaLink && link is ODataDeltaLink ||
                    state == WriterState.DeltaDeletedLink && link is ODataDeltaDeletedLink,
                    "link must be either DeltaLink or DeltaDeletedLink.");
                Debug.Assert(writerBehavior != null, "writerBehavior != null");

                this.serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(serializationInfo);
            }
            /// <summary>
            /// Constructor to create a new feed scope.
            /// </summary>
            /// <param name="item">The feed for the new scope.</param>
            /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
            /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
            /// <param name="selectedProperties">The selected properties of this scope.</param>
            /// <param name="odataUri">The ODataUri info of this scope.</param>
            protected DeltaFeedScope(ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
                : base(WriterState.DeltaFeed, item, navigationSource, entityType, selectedProperties, odataUri)
            {
                Debug.Assert(item != null, "item != null");

                var feed = item as ODataDeltaFeed;
                Debug.Assert(feed != null, "feed must be DeltaFeed.");

                this.serializationInfo = feed.SerializationInfo;
            }
            /// <summary>
            /// Constructor to create a new entry scope.
            /// </summary>
            /// <param name="state">The writer state of this scope.</param>
            /// <param name="entry">The entry for the new scope.</param>
            /// <param name="serializationInfo">The serialization info for the current entry.</param>
            /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
            /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
            /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
            /// <param name="selectedProperties">The selected properties of this scope.</param>
            /// <param name="odataUri">The ODataUri info of this scope.</param>
            protected DeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
                : base(state, entry, navigationSource, entityType, selectedProperties, odataUri)
            {
                Debug.Assert(entry != null, "entry != null");
                Debug.Assert(
                    state == WriterState.DeltaEntry && entry is ODataEntry ||
                    state == WriterState.DeltaDeletedEntry && entry is ODataDeltaDeletedEntry,
                    "entry must be either DeltaEntry or DeltaDeletedEntry.");
                Debug.Assert(writerBehavior != null, "writerBehavior != null");

                this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, /*writingResponse*/ true);
                this.serializationInfo = serializationInfo;
            }
 /// <summary>
 /// Constructor creating a new writer scope.
 /// </summary>
 /// <param name="state">The writer state of this scope.</param>
 /// <param name="item">The item attached to this scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal Scope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     this.state = state;
     this.item = item;
     this.EntityType = entityType;
     this.NavigationSource = navigationSource;
     this.selectedProperties = selectedProperties;
     this.odataUri = odataUri;
 }
        public void WriteEntityInDeltaFeedWithSelectExpand()
        {
            this.TestInit(this.GetModel());

            ODataDeltaFeed feed = new ODataDeltaFeed();

            ODataEntry orderEntry= new ODataEntry()
            {
                Properties = new List<ODataProperty>
                {
                    new ODataProperty
                    {
                        Name = "ShippingAddress",
                        Value = new ODataComplexValue
                        {
                            Properties = new List<ODataProperty>
                            {
                                new ODataProperty { Name = "City", Value = "Shanghai" },
                            }
                        }
                    }
                },
                SerializationInfo = new ODataFeedAndEntrySerializationInfo
                {
                    NavigationSourceEntityTypeName = "Order",
                    NavigationSourceKind = EdmNavigationSourceKind.EntitySet,
                    NavigationSourceName = "Orders"
                },
            };


           var result = new ODataQueryOptionParser(this.GetModel(), this.GetCustomerType(), this.GetCustomers(), new Dictionary<string, string> { { "$expand", "Orders($select=ShippingAddress)" }, { "$select", "ContactName" } }).ParseSelectAndExpand();

            ODataUri odataUri = new ODataUri()
            {
                ServiceRoot = new Uri("http://host/service"),
                SelectAndExpand = result
            };

            var outputContext = CreateJsonLightOutputContext(this.stream, this.GetModel(), false, odataUri);
            ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType());
            writer.WriteStart(feed);
            writer.WriteStart(orderEntry);
            writer.WriteEnd();
            writer.WriteEnd();
            writer.Flush();

            this.TestPayload().Should().Be("{\"@odata.context\":\"http://host/service/$metadata#Products(ContactName,Orders,Orders(ShippingAddress))/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Orders/$entity\",\"ShippingAddress\":{\"City\":\"Shanghai\"}}]}");
        }
 /// <summary>
 /// Constructor creating a new reader scope.
 /// </summary>
 /// <param name="navigationLinkInfo">The navigation link info attached to this scope.</param>
 /// <param name="navigationSource">The navigation source we are going to read entities for.</param>
 /// <param name="expectedEntityType">The expected type for the scope.</param>
 /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param> 
 /// <remarks>The <paramref name="expectedEntityType"/> has the following meaning
 ///   it's the expected base type the entries in the expanded link (either the single entry
 ///   or entries in the expanded feed).
 /// In all cases the specified type must be an entity type.</remarks>
 internal JsonLightNavigationLinkScope(ODataJsonLightReaderNavigationLinkInfo navigationLinkInfo, IEdmNavigationSource navigationSource, IEdmEntityType expectedEntityType, ODataUri odataUri)
     : base(ODataReaderState.NavigationLinkStart, navigationLinkInfo.NavigationLink, navigationSource, expectedEntityType, odataUri)
 {
     this.NavigationLinkInfo = navigationLinkInfo;   
 }
Esempio n. 42
0
        /// <summary>
        /// Parse a full Uri into its contingent parts with semantic meaning attached to each part. 
        /// See <see cref="ODataUri"/>.
        /// </summary>
        /// <returns>An <see cref="ODataUri"/> representing the full uri.</returns>
        public ODataUri ParseUri()
        {
            ExceptionUtils.CheckArgumentNotNull(this.configuration.Model, "model");
            ExceptionUtils.CheckArgumentNotNull(this.fullUri, "fullUri");

            ODataPath path = this.ParsePath();
            SelectExpandClause selectExpand = this.ParseSelectAndExpand();
            FilterClause filter = this.ParseFilter();
            OrderByClause orderBy = this.ParseOrderBy();
            SearchClause search = this.ParseSearch();
            ApplyClause apply = this.ParseApply();
            long? top = this.ParseTop();
            long? skip = this.ParseSkip();
            bool? count = this.ParseCount();
            string skipToken = this.ParseSkipToken();
            string deltaToken = this.ParseDeltaToken();

            // TODO:  check it shouldn't be empty
            List<QueryNode> boundQueryOptions = new List<QueryNode>();

            ODataUri odataUri = new ODataUri(this.ParameterAliasValueAccessor, path, boundQueryOptions, selectExpand, filter, orderBy, search, apply, skip, top, count);
            odataUri.ServiceRoot = this.serviceRoot;
            odataUri.SkipToken = skipToken;
            odataUri.DeltaToken = deltaToken;
            return odataUri;
        }
 /// <summary>
 /// Constructor to create a new JSON Light navigation link scope.
 /// </summary>
 /// <param name="writerState">The writer state for the new scope.</param>
 /// <param name="navLink">The navigation link for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal JsonLightNavigationLinkScope(WriterState writerState, ODataNavigationLink navLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(writerState, navLink, navigationSource, entityType, skipWriting, selectedProperties, odataUri)
 {
 }
            /// <summary>
            /// Constructor creating a new reader scope.
            /// </summary>
            /// <param name="readerState">The reader state of the new scope that is being created.</param>
            /// <param name="entry">The item attached to this scope.</param>
            /// <param name="navigationSource">The navigation source we are going to read entities for.</param>
            /// <param name="expectedEntityType">The expected type for the scope.</param>
            /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker for this entry scope.</param>
            /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param>
            /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param>
            /// <remarks>The <paramref name="expectedEntityType"/> has the following meaning
            ///   it's the expected base type of the entry. If the entry has no type name specified
            ///   this type will be assumed. Otherwise the specified type name must be
            ///   the expected type or a more derived type.
            /// In all cases the specified type must be an entity type.</remarks>
            internal JsonLightEntryScope(
                ODataReaderState readerState,
                ODataEntry entry,
                IEdmNavigationSource navigationSource,
                IEdmEntityType expectedEntityType,
                DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
                SelectedPropertiesNode selectedProperties,
                ODataUri odataUri)
                : base(readerState, entry, navigationSource, expectedEntityType, odataUri)
            {
                Debug.Assert(
                    readerState == ODataReaderState.EntryStart || readerState == ODataReaderState.EntryEnd,
                    "readerState == ODataReaderState.EntryStart || readerState == ODataReaderState.EntryEnd");

                this.DuplicatePropertyNamesChecker = duplicatePropertyNamesChecker;
                this.SelectedProperties = selectedProperties;
            }
 /// <summary>
 /// Constructor creating a new reader scope.
 /// </summary>
 /// <param name="feed">The item attached to this scope.</param>
 /// <param name="navigationSource">The navigation source we are going to read entities for.</param>
 /// <param name="expectedEntityType">The expected type for the scope.</param>
 /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param>
 /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param>
 /// <remarks>The <paramref name="expectedEntityType"/> has the following meaning
 ///   it's the expected base type of the entries in the feed.
 ///   note that it might be a more derived type than the base type of the entity set for the feed.
 /// In all cases the specified type must be an entity type.</remarks>
 internal JsonLightFeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType expectedEntityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(ODataReaderState.FeedStart, feed, navigationSource, expectedEntityType, odataUri)
 {
     this.SelectedProperties = selectedProperties;
 }
 /// <summary>
 /// Create a new entry scope.
 /// </summary>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <returns>The newly create scope.</returns>
 protected override EntryScope CreateEntryScope(ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     return new JsonLightEntryScope(
         entry,
         this.GetEntrySerializationInfo(entry),
         navigationSource,
         entityType,
         skipWriting,
         this.jsonLightOutputContext.WritingResponse,
         this.jsonLightOutputContext.MessageWriterSettings.WriterBehavior,
         selectedProperties,
         odataUri,
         this.jsonLightOutputContext.MessageWriterSettings.EnableFullValidation);
 }
 /// <summary>
 /// Create a new feed scope.
 /// </summary>
 /// <param name="feed">The feed for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <returns>The newly create scope.</returns>
 protected override FeedScope CreateFeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     return new JsonLightFeedScope(feed, navigationSource, entityType, skipWriting, selectedProperties, odataUri);
 }
        private static ODataJsonLightOutputContext CreateJsonLightOutputContext(MemoryStream stream, IEdmModel userModel, bool fullMetadata = false, ODataUri uri = null)
        {
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings { Version = ODataVersion.V4, AutoComputePayloadMetadataInJson = true, ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*") };
            settings.SetServiceDocumentUri(new Uri("http://host/service"));
            if (uri != null)
            {
                settings.ODataUri = uri;
            }

            IEnumerable<KeyValuePair<string, string>> parameters;
            if (fullMetadata)
            {
                parameters = new[] { new KeyValuePair<string, string>("odata.metadata", "full") };
            }
            else
            {
                parameters = new List<KeyValuePair<string, string>>();
            }

            ODataMediaType mediaType = new ODataMediaType("application", "json", parameters);
            return new ODataJsonLightOutputContext(
                ODataFormat.Json,
                new NonDisposingStream(stream),
                mediaType,
                Encoding.UTF8,
                settings,
                /*writingResponse*/ true,
                /*synchronous*/ true,
                userModel ?? EdmCoreModel.Instance,
                /*urlResolver*/ null);
        }
 /// <summary>
 /// Constructor to create a new feed scope.
 /// </summary>
 /// <param name="feed">The feed for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal JsonLightDeltaFeedScope(ODataItem feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(feed, navigationSource, entityType, selectedProperties, odataUri)
 {
 }
        /// <summary>
        /// Create a new writer scope.
        /// </summary>
        /// <param name="state">The writer state of the scope to create.</param>
        /// <param name="item">The item attached to the scope to create.</param>
        /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
        /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
        /// <param name="selectedProperties">The selected properties of this scope.</param>
        /// <param name="odataUri">The OdataUri info of this scope.</param>
        private void PushScope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
        {
            Debug.Assert(
                state == WriterState.Error ||
                state == WriterState.DeltaEntry && item is ODataEntry ||
                state == WriterState.DeltaDeletedEntry && item is ODataDeltaDeletedEntry ||
                state == WriterState.DeltaFeed && item is ODataDeltaFeed ||
                state == WriterState.DeltaLink && item is ODataDeltaLink ||
                state == WriterState.DeltaDeletedLink && item is ODataDeltaDeletedLink ||
                state == WriterState.Start && item == null ||
                state == WriterState.Completed && item == null,
                "Writer state and associated item do not match.");

            Scope scope;
            switch (state)
            {
                case WriterState.DeltaEntry:
                    scope = this.CreateDeltaEntryScope(WriterState.DeltaEntry, item, navigationSource, entityType, selectedProperties, odataUri);
                    break;
                case WriterState.DeltaDeletedEntry:
                    scope = this.CreateDeltaEntryScope(WriterState.DeltaDeletedEntry, item, navigationSource, entityType, selectedProperties, odataUri);
                    break;
                case WriterState.DeltaFeed:
                    scope = this.CreateDeltaFeedScope(item, navigationSource, entityType, selectedProperties, odataUri);
                    break;
                case WriterState.DeltaLink:
                    scope = this.CreateDeltaLinkScope(WriterState.DeltaLink, item, navigationSource, entityType, selectedProperties, odataUri);
                    break;
                case WriterState.DeltaDeletedLink:
                    scope = this.CreateDeltaLinkScope(WriterState.DeltaDeletedLink, item, navigationSource, entityType, selectedProperties, odataUri);
                    break;
                case WriterState.Start:                     // fall through
                case WriterState.Completed:                 // fall through
                case WriterState.Error:
                    scope = new Scope(state, item, navigationSource, entityType, selectedProperties, odataUri);
                    break;
                default:
                    string errorMessage = Strings.General_InternalError(InternalErrorCodes.ODataWriterCore_Scope_Create_UnreachableCodePath);
                    Debug.Assert(false, errorMessage);
                    throw new ODataException(errorMessage);
            }

            this.scopes.Push(scope);
        }
 /// <summary>
 /// Constructor to create a new delta link scope.
 /// </summary>
 /// <param name="state">The writer state of this scope.</param>
 /// <param name="link">The link for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal JsonLightDeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(state, link, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri)
 {
 }
 /// <summary>
 /// Create a new delta feed scope.
 /// </summary>
 /// <param name="feed">The feed for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <returns>The newly create scope.</returns>
 private DeltaFeedScope CreateDeltaFeedScope(ODataItem feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     return new JsonLightDeltaFeedScope(feed, navigationSource, entityType, selectedProperties, odataUri);
 }
        /// <summary>
        /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload
        /// metadata properties (like EditLink) of the entry may return a value computed by convention, 
        /// depending on the metadata level and whether the user manually set an edit link or not.
        /// </summary>
        /// <param name="entry">The entry to create the metadata builder for.</param>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param>
        /// <param name="serializationInfo">The serialization info for the entry.</param>
        /// <param name="actualEntityType">The entity type of the entry.</param>
        /// <param name="selectedProperties">The selected properties of this scope.</param>
        /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param>
        /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses.
        /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param>
        /// <param name="odataUri">The OData Uri.</param>
        /// <returns>The created metadata builder.</returns>
        internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder(
            ODataEntry entry, 
            IODataFeedAndEntryTypeContext typeContext, 
            ODataFeedAndEntrySerializationInfo serializationInfo, 
            IEdmEntityType actualEntityType, 
            SelectedPropertiesNode selectedProperties, 
            bool isResponse, 
            bool? keyAsSegment,
            ODataUri odataUri)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(typeContext != null, "typeContext != null");
            Debug.Assert(selectedProperties != null, "selectedProperties != null");

            IODataMetadataContext metadataContext = new ODataMetadataContext(
                isResponse,
                this.model,
                this.NonNullMetadataDocumentUri,
                odataUri);
            
            UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(keyAsSegment, typeContext);
            ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri, urlConvention);

            IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, actualEntityType, metadataContext, selectedProperties);
            return new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, uriBuilder);
        }
 /// <summary>
 /// Create a new delta link scope.
 /// </summary>
 /// <param name="state">The writer state of the scope to create.</param>
 /// <param name="link">The link for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <returns>The newly create scope.</returns>
 private DeltaLinkScope CreateDeltaLinkScope(WriterState state, ODataItem link, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     return new JsonLightDeltaLinkScope(
         state,
         link,
         this.GetLinkSerializationInfo(link),
         navigationSource,
         entityType,
         this.jsonLightOutputContext.MessageWriterSettings.WriterBehavior,
         selectedProperties,
         odataUri);
 }
 /// <summary>
 /// Creates a new JSON Light navigation link scope.
 /// </summary>
 /// <param name="writerState">The writer state for the new scope.</param>
 /// <param name="navLink">The navigation link for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <returns>The newly created JSON Light  navigation link scope.</returns>
 protected override NavigationLinkScope CreateNavigationLinkScope(WriterState writerState, ODataNavigationLink navLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     return new JsonLightNavigationLinkScope(writerState, navLink, navigationSource, entityType, skipWriting, selectedProperties, odataUri);
 }
        public void WriteContainedEntityInDeltaFeedWithSelectExpand()
        {
            this.TestInit(this.GetModel());

            ODataDeltaFeed feed = new ODataDeltaFeed();

            ODataEntry entry = new ODataEntry()
            {
                TypeName = "MyNS.Product",
                Properties = new[]
                {
                    new ODataProperty {Name = "Id", Value = new ODataPrimitiveValue(1)}, 
                    new ODataProperty {Name = "Name", Value = new ODataPrimitiveValue("Car")},
                },
            };

            ODataEntry containedEntry = new ODataEntry()
            {
                TypeName = "MyNS.ProductDetail",
                Properties = new[]
                {
                    new ODataProperty {Name = "Id", Value = new ODataPrimitiveValue(1)}, 
                    new ODataProperty {Name = "Detail", Value = new ODataPrimitiveValue("made in china")},
                },
            };

            containedEntry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyNS.ProductDetail",
                NavigationSourceName = "Products(1)/Details",
                NavigationSourceKind = EdmNavigationSourceKind.ContainedEntitySet
            });


            var result = new ODataQueryOptionParser(this.GetModel(), this.GetProductType(), this.GetProducts(), new Dictionary<string, string> { { "$expand", "Details($select=Detail)" }, { "$select", "Name" } }).ParseSelectAndExpand();

            ODataUri odataUri = new ODataUri()
            {
                ServiceRoot = new Uri("http://host/service"),
                SelectAndExpand = result
            };

            var outputContext = CreateJsonLightOutputContext(this.stream, this.GetModel(), false, odataUri);
            ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType());
            writer.WriteStart(feed);
            writer.WriteStart(containedEntry);
            writer.WriteEnd();
            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.WriteEnd();
            writer.Flush();

            this.TestPayload().Should().Be("{\"@odata.context\":\"http://host/service/$metadata#Products(Name,Details,Details(Detail))/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Products(1)/Details/$entity\",\"Id\":1,\"Detail\":\"made in china\"},{\"Id\":1,\"Name\":\"Car\"}]}");
        }
        private string GetWriterOutputForContentTypeAndKnobValue(
            string contentType,
            bool autoComputePayloadMetadataInJson,
            ODataItem[] itemsToWrite,
            EdmModel edmModel,
            IEdmEntitySetBase edmEntitySet,
            EdmEntityType edmEntityType,
            string selectClause = null,
            string expandClause = null,
            string resourcePath = null,
            bool enableFullValidation = true)
        {
            MemoryStream outputStream = new MemoryStream();
            IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream };
            message.SetHeader("Content-Type", contentType);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings()
            {
                AutoComputePayloadMetadataInJson = autoComputePayloadMetadataInJson,
                EnableFullValidation = enableFullValidation
            };

            var result = new ODataQueryOptionParser(edmModel, edmEntityType, edmEntitySet, new Dictionary<string, string> { { "$expand", expandClause }, { "$select", selectClause } }).ParseSelectAndExpand();

            ODataUri odataUri = new ODataUri()
            {
                ServiceRoot = new Uri("http://example.org/odata.svc"),
                SelectAndExpand = result
            };

            if (resourcePath != null)
            {
                Uri requestUri = new Uri("http://example.org/odata.svc/" + resourcePath);
                odataUri.RequestUri = requestUri;
                odataUri.Path = new ODataUriParser(edmModel, new Uri("http://example.org/odata.svc/"), requestUri).ParsePath();
            }

            settings.ODataUri = odataUri;

            string output;
            using (var messageWriter = new ODataMessageWriter(message, settings, edmModel))
            {
                int currentIdx = 0;

                if (itemsToWrite[currentIdx] is ODataFeed)
                {
                    ODataWriter writer = messageWriter.CreateODataFeedWriter(edmEntitySet, edmEntityType);
                    this.WriteFeed(writer, itemsToWrite, ref currentIdx);
                }
                else if (itemsToWrite[currentIdx] is ODataEntry)
                {
                    ODataWriter writer = messageWriter.CreateODataEntryWriter(edmEntitySet, edmEntityType);
                    this.WriteEntry(writer, itemsToWrite, ref currentIdx);
                }
                else
                {
                    Assert.True(false, "Top level item to write must be entry or feed.");
                }

                currentIdx.Should().Be(itemsToWrite.Length, "Invalid list of items to write.");

                outputStream.Seek(0, SeekOrigin.Begin);
                output = new StreamReader(outputStream).ReadToEnd();
            }

            return output;
        }
 /// <summary>
 /// Constructor to create a new feed scope.
 /// </summary>
 /// <param name="feed">The feed for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal JsonLightFeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(feed, navigationSource, entityType, skipWriting, selectedProperties, odataUri)
 {
 }
Esempio n. 59
0
 protected override ODataWriterCore.EntryScope CreateEntryScope(ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Constructor to create a new entry scope.
 /// </summary>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <param name="enableValidation">Enable validation or not.</param>
 internal JsonLightEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri, bool enableValidation)
     : base(entry, serializationInfo, navigationSource, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties, odataUri, enableValidation)
 {
 }