/// <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); }
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); }
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); }
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); }
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); }
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)); }
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); } }
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); }
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); }
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); } }
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)); }
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)); }
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); }
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); }
/// <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); }
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); }
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); }
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); } } }
/// <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); }
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 }
/// <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); }
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); }
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); }
/// <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)); } }
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; }
/// <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) { }
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) { }