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.AreEqual(uri.ParameterAliasNodes.Count, 0); ODataUriBuilder builder = new ODataUriBuilder(ODataUrlConventions.Default, uri); Uri res = builder.BuildUri(); Assert.AreEqual(new Uri("http://gobbledygook/People?$top=5&$skip=4"), res); }
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.AreEqual(new Uri("http://gobbledygook/GetPet1(id=1)"), actual); }
internal Scope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType expectedEntityType, ODataUri odataUri) { Debug.Assert( state == ODataReaderState.Exception && item == null || state == ODataReaderState.EntryStart && (item == null || item is ODataEntry) || state == ODataReaderState.EntryEnd && (item == null || item is ODataEntry) || state == ODataReaderState.FeedStart && item is ODataFeed || state == ODataReaderState.FeedEnd && item is ODataFeed || state == ODataReaderState.NavigationLinkStart && item is ODataNavigationLink || state == ODataReaderState.NavigationLinkEnd && item is ODataNavigationLink || state == ODataReaderState.EntityReferenceLink && item is ODataEntityReferenceLink || state == ODataReaderState.Start && item == null || state == ODataReaderState.Completed && item == null, "Reader state and associated item do not match."); this.state = state; this.item = item; this.EntityType = expectedEntityType; this.NavigationSource = navigationSource; this.odataUri = odataUri; }
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')\""); }
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> /// 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 EntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri, bool enableValidation = true) : base(WriterState.Entry, entry, navigationSource, entityType, skipWriting, selectedProperties, odataUri) { Debug.Assert(writerBehavior != null, "writerBehavior != null"); if (entry != null) { this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, writingResponse, !enableValidation); } this.serializationInfo = serializationInfo; }
/// <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 FeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(WriterState.Feed, feed, navigationSource, entityType, skipWriting, selectedProperties, odataUri) { this.serializationInfo = feed.SerializationInfo; }
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(), 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(); string payload = this.TestFinish(); payload.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\"}]}"); }
/// <summary> /// Create ODataContextUrlInfo from ODataFeedAndEntryTypeContext /// </summary> /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param> /// <param name="isSingle">Whether target is single item.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, bool isSingle, ODataUri odataUri = null) { Debug.Assert(typeContext != null, "typeContext != null"); return new ODataContextUrlInfo() { isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet, IsUnknownEntitySet = typeContext.NavigationSourceKind == EdmNavigationSourceKind.UnknownEntitySet, navigationSource = typeContext.NavigationSourceName, TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName, TypeName = typeContext.NavigationSourceFullTypeName, IncludeFragmentItemSelector = isSingle && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton, odataUri = odataUri }; }
/// <summary> /// Create ODataContextUrlInfo for OdataValue. /// </summary> /// <param name="value">The ODataValue to be used.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <param name="model">The model used to handle unsigned int conversions.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataValue value, ODataUri odataUri = null, IEdmModel model = null) { return new ODataContextUrlInfo() { TypeName = GetTypeNameForValue(value, model), odataUri = odataUri }; }
/// <summary> /// Create ODataContextUrlInfo from ODataFeedAndEntryTypeContext /// </summary> /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param> /// <param name="isSingle">Whether target is single item.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, bool isSingle, ODataUri odataUri = null) { Debug.Assert(typeContext != null, "typeContext != null"); return(new ODataContextUrlInfo() { isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet, navigationSource = typeContext.NavigationSourceName, TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName, TypeName = typeContext.NavigationSourceEntityTypeName, IncludeFragmentItemSelector = isSingle && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton, odataUri = odataUri }); }
/// <summary> /// Creates a new 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 navigation link scope.</returns> protected virtual NavigationLinkScope CreateNavigationLinkScope(WriterState writerState, ODataNavigationLink navLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new NavigationLinkScope(writerState, navLink, navigationSource, entityType, skipWriting, selectedProperties, odataUri); }
/// <summary> /// Constructor to create a new 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 NavigationLinkScope(WriterState writerState, ODataNavigationLink navLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(writerState, navLink, navigationSource, entityType, skipWriting, selectedProperties, odataUri) { }
private static void BuildFilterWithBinaryOperator() { var personTypeRef = new EdmEntityTypeReference(TripPinModel.Person, false); var friendsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Friends"); var firstNameProp = TripPinModel.Person.FindProperty("FirstName"); var lastNameProp = TripPinModel.Person.FindProperty("LastName"); var topIt = new EntityRangeVariable("$it", personTypeRef, TripPinModel.PeopleSet); var topItRef = new EntityRangeVariableReferenceNode("$it", topIt); var friendsNavNode = new CollectionNavigationNode(friendsProp, topItRef); var e0 = new EntityRangeVariable("e0", personTypeRef, friendsNavNode); var e0Ref = new EntityRangeVariableReferenceNode("e0", e0); var fun1 = new SingleValueFunctionCallNode( "startswith", new QueryNode[] { new SingleValuePropertyAccessNode(e0Ref, firstNameProp), new ConstantNode("var1", "'var1'") }, EdmCoreModel.Instance.GetBoolean(false)); var friendsNavNode2 = new CollectionNavigationNode(friendsProp, e0Ref); var e1 = new EntityRangeVariable("e1", personTypeRef, friendsNavNode2); var e1Ref = new EntityRangeVariableReferenceNode("e1", e1); var fun2 = new SingleValueFunctionCallNode( "contains", new QueryNode[] { new SingleValuePropertyAccessNode(e1Ref, lastNameProp), new ConstantNode("var2", "'var2'") }, EdmCoreModel.Instance.GetBoolean(false)); // Actually $it also needed, but would not be used in UriBuilder, so omit it here. var any2 = new AnyNode(new Collection<RangeVariable> { e1 }, e1) { Body = fun2, Source = friendsNavNode2 }; var any1 = new AnyNode(new Collection<RangeVariable> { e0 }, e0) { Body = new BinaryOperatorNode(BinaryOperatorKind.And, fun1, any2), Source = friendsNavNode }; var odataUri = new ODataUri { Path = new ODataPath(new EntitySetSegment(TripPinModel.PeopleSet)), ServiceRoot = TripPinRoot, Filter = new FilterClause(any1, topIt) }; var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri); Console.WriteLine(builder.BuildUri()); // http://services.odata.org/V4/TripPinService/People?$filter=Friends%2Fany( // e0:startswith(e0%2FFirstName%2C'var1') and e0%2FFriends%2Fany(e1:contains(e1%2FLastName%2C'var2'))) }
private static void BuildFilterWithNestedAny() { var personTypeRef = new EdmEntityTypeReference(TripPinModel.Person, false); var tripTypeRef = new EdmEntityTypeReference(TripPinModel.Trip, false); var friendsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Friends"); var tripsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Trips"); var budgetProp = TripPinModel.Trip.FindProperty("Budget"); var topIt = new EntityRangeVariable("$it", personTypeRef, TripPinModel.PeopleSet); var topItRef = new EntityRangeVariableReferenceNode("$it", topIt); var friendsNavNode0 = new CollectionNavigationNode(friendsProp, topItRef); var e0 = new EntityRangeVariable("e0", personTypeRef, friendsNavNode0); var e0Ref = new EntityRangeVariableReferenceNode("e0", e0); var friendsNavNode1 = new CollectionNavigationNode(friendsProp, e0Ref); var e1 = new EntityRangeVariable("e1", personTypeRef, friendsNavNode1); var e1Ref = new EntityRangeVariableReferenceNode("e1", e1); var tripNavNode = new CollectionNavigationNode(tripsProp, e1Ref); var e2 = new EntityRangeVariable("e2", tripTypeRef, friendsNavNode1); var e2Ref = new EntityRangeVariableReferenceNode("e2", e2); var bugetNode = new SingleValuePropertyAccessNode(e2Ref, budgetProp); var gt = new BinaryOperatorNode( BinaryOperatorKind.GreaterThan, bugetNode, new ConstantNode(1200, "1200")); var any2 = new AnyNode(new Collection<RangeVariable> { e2 }, e2) { Body = gt, Source = tripNavNode }; var any1 = new AnyNode(new Collection<RangeVariable> { e1 }, e1) { Body = any2, Source = friendsNavNode1 }; var any0 = new AnyNode(new Collection<RangeVariable> { e0 }, e0) { Body = any1, Source = friendsNavNode0 }; var odataUri = new ODataUri { Path = new ODataPath(new EntitySetSegment(TripPinModel.PeopleSet)), ServiceRoot = TripPinRoot, Filter = new FilterClause(any0, topIt) }; var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri); Console.WriteLine(builder.BuildUri()); // http://services.odata.org/V4/TripPinService/People?$filter=Friends%2Fany(e0:e0%2FFriends%2Fany(e1:e1%2FTrips%2Fany(e2:e2%2FBudget gt 1200))) }
private static ODataJsonLightOutputContext CreateJsonLightOutputContext(MemoryStream stream, IEdmModel userModel, 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; } ODataMediaType mediaType = new ODataMediaType("application", "json", new List<KeyValuePair<string, string>>()); //mediaType.Parameters.Add(new KeyValuePair<string, string>("odata.metadata", "full")); return new ODataJsonLightOutputContext( ODataFormat.Json, new NonDisposingStream(stream), mediaType, Encoding.UTF8, settings, /*writingResponse*/ true, /*synchronous*/ true, userModel ?? EdmCoreModel.Instance, /*urlResolver*/ null); }
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(), odataUri); ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType()); writer.WriteStart(feed); writer.WriteStart(orderEntry); writer.WriteEnd(); writer.WriteEnd(); writer.Flush(); string payload = this.TestFinish(); payload.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> /// 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 abstract EntryScope CreateEntryScope(ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri);
protected override ODataWriterCore.EntryScope CreateEntryScope(ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { throw new NotImplementedException(); }
private static string WriteJsonLightEntry(bool isRequest, Uri serviceDocumentUri, bool specifySet, ODataEntry odataEntry, IEdmNavigationSource entitySet, IEdmEntityType entityType, ODataUri odataUri) { var model = new EdmModel(); model.AddElement(new EdmEntityContainer("Fake", "Container_sub")); var stream = new MemoryStream(); var message = new InMemoryMessage { Stream = stream }; var settings = new ODataMessageWriterSettings { Version = ODataVersion.V4, AutoComputePayloadMetadataInJson = true }; settings.ODataUri = odataUri; settings.SetServiceDocumentUri(serviceDocumentUri); settings.SetContentType(ODataFormat.Json); settings.SetContentType("application/json;odata.metadata=full", null); ODataMessageWriter messageWriter; if (isRequest) { messageWriter = new ODataMessageWriter((IODataRequestMessage)message, settings, TestUtils.WrapReferencedModelsToMainModel("Fake", "Container", model)); } else { messageWriter = new ODataMessageWriter((IODataResponseMessage)message, settings, TestUtils.WrapReferencedModelsToMainModel("Fake", "Container", model)); } var entryWriter = messageWriter.CreateODataEntryWriter(specifySet ? entitySet : null, entityType); entryWriter.WriteStart(odataEntry); entryWriter.WriteEnd(); entryWriter.Flush(); var actual = Encoding.UTF8.GetString(stream.ToArray()); return actual; }
public void ExpandWithNestedQueryOptionsShouldWork() { var ervFilter = new EntityRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); var ervOrderby = new EntityRangeVariable(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 EntityRangeVariableReferenceNode("$it", ervFilter), HardCodedTestModel.GetDogColorProp()), new ConstantNode("Brown", "'Brown'")), ervFilter), new OrderByClause( null, new SingleValuePropertyAccessNode(new EntityRangeVariableReferenceNode("$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 = new ODataUriBuilder(ODataUrlConventions.Default, uri).BuildUri(); Assert.AreEqual("http://gobbledygook/People?$expand=" + Uri.EscapeDataString("MyDog($filter=Color eq 'Brown';$orderby=Color;$top=1;$count=true;$search=termX)"), actualUri.OriginalString); }
/// <summary> /// Create ODataContextUrlInfo from basic information /// </summary> /// <param name="navigationSource">Navigation source for current element.</param>\ /// <param name="expectedEntityTypeName">The expectedEntity for current element.</param> /// <param name="isSingle">Whether target is single item.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(IEdmNavigationSource navigationSource, string expectedEntityTypeName, bool isSingle, ODataUri odataUri) { EdmNavigationSourceKind kind = navigationSource.NavigationSourceKind(); string navigationSourceEntityType = navigationSource.EntityType().FullName(); return(new ODataContextUrlInfo() { isContained = kind == EdmNavigationSourceKind.ContainedEntitySet, navigationSource = navigationSource.Name, TypeCast = navigationSourceEntityType == expectedEntityTypeName ? null : expectedEntityTypeName, TypeName = navigationSourceEntityType, IncludeFragmentItemSelector = isSingle && kind != EdmNavigationSourceKind.Singleton, odataUri = odataUri }); }
private string GetWriterOutputForContentTypeAndKnobValue(string contentType, bool autoComputePayloadMetadataInJson, ODataItem[] itemsToWrite, EdmModel edmModel, IEdmEntitySetBase edmEntitySet, EdmEntityType edmEntityType, string selectClause = null, string expandClause = null, string resourcePath = null) { MemoryStream outputStream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream }; message.SetHeader("Content-Type", contentType); ODataMessageWriterSettings settings = new ODataMessageWriterSettings() { AutoComputePayloadMetadataInJson = autoComputePayloadMetadataInJson, }; var result = new ODataQueryOptionParser(edmModel, edmEntityType, edmEntitySet, new Dictionary<string, string> { { "$select", selectClause }, { "$expand", expandClause } }).ParseSelectAndExpand(); ODataUri odataUri = new ODataUri() { ServiceRoot = new Uri("http://example.com"), SelectAndExpand = result }; if (resourcePath != null) { Uri requestUri = new Uri("http://example.com/" + resourcePath); odataUri.RequestUri = requestUri; odataUri.Path = new ODataUriParser(edmModel, new Uri("http://example.com"), 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.Fail("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> /// Create contextUrlInfo for delta /// </summary> /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param> /// <param name="kind">The delta kind.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataUri odataUri = null) { Debug.Assert(typeContext != null, "typeContext != null"); ODataContextUrlInfo contextUriInfo = new ODataContextUrlInfo() { isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet, navigationSource = typeContext.NavigationSourceName, TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName, TypeName = typeContext.NavigationSourceEntityTypeName, IncludeFragmentItemSelector = kind == ODataDeltaKind.Entry && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton, DeltaKind = kind, }; // Only use odata uri in with model case. if (typeContext is ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel) { contextUriInfo.odataUri = odataUri; } return(contextUriInfo); }
private void PushScope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { Debug.Assert( state == WriterState.Error || state == WriterState.Entry && (item == null || item is ODataEntry) || state == WriterState.Feed && item is ODataFeed || state == WriterState.NavigationLink && item is ODataNavigationLink || state == WriterState.NavigationLinkWithContent && item is ODataNavigationLink || state == WriterState.Start && item == null || state == WriterState.Completed && item == null, "Writer state and associated item do not match."); Scope scope; switch (state) { case WriterState.Entry: scope = this.CreateEntryScope((ODataEntry)item, navigationSource, entityType, skipWriting, selectedProperties, odataUri); break; case WriterState.Feed: scope = this.CreateFeedScope((ODataFeed)item, navigationSource, entityType, skipWriting, selectedProperties, odataUri); break; case WriterState.NavigationLink: // fall through case WriterState.NavigationLinkWithContent: scope = this.CreateNavigationLinkScope(state, (ODataNavigationLink)item, navigationSource, entityType, skipWriting, selectedProperties, odataUri); break; case WriterState.Start: // fall through case WriterState.Completed: // fall through case WriterState.Error: scope = new Scope(state, item, navigationSource, entityType, skipWriting, 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> /// Create ODataContextUrlInfo from basic information /// </summary> /// <param name="navigationSource">Navigation source for current element.</param>\ /// <param name="expectedEntityTypeName">The expectedEntity for current element.</param> /// <param name="isSingle">Whether target is single item.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(IEdmNavigationSource navigationSource, string expectedEntityTypeName, bool isSingle, ODataUri odataUri) { EdmNavigationSourceKind kind = navigationSource.NavigationSourceKind(); string navigationSourceEntityType = navigationSource.EntityType().FullName(); return new ODataContextUrlInfo() { isContained = kind == EdmNavigationSourceKind.ContainedEntitySet, IsUnknownEntitySet = kind == EdmNavigationSourceKind.UnknownEntitySet, navigationSource = navigationSource.Name, TypeCast = navigationSourceEntityType == expectedEntityTypeName ? null : expectedEntityTypeName, TypeName = navigationSourceEntityType, IncludeFragmentItemSelector = isSingle && kind != EdmNavigationSourceKind.Singleton, odataUri = odataUri }; }
/// <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="skipWriting">true if the content of this scope 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 Scope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { this.state = state; this.item = item; this.entityType = entityType; this.navigationSource = navigationSource; this.skipWriting = skipWriting; this.selectedProperties = selectedProperties; this.odataUri = odataUri; }
/// <summary> /// Create contextUrlInfo for delta /// </summary> /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param> /// <param name="kind">The delta kind.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataUri odataUri = null) { Debug.Assert(typeContext != null, "typeContext != null"); ODataContextUrlInfo contextUriInfo = new ODataContextUrlInfo() { isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet, IsUnknownEntitySet = typeContext.NavigationSourceKind == EdmNavigationSourceKind.UnknownEntitySet, navigationSource = typeContext.NavigationSourceName, TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName, TypeName = typeContext.NavigationSourceEntityTypeName, IncludeFragmentItemSelector = kind == ODataDeltaKind.Entry && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton, DeltaKind = kind, }; // Only use odata uri in with model case. if (typeContext is ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel) { contextUriInfo.odataUri = odataUri; } return contextUriInfo; }
/// <summary> /// Constructor of the ODataUriBuilder /// </summary> /// <param name="urlConventions">ODataUriBuilder constructor</param> /// <param name="odataUri">semantic tree of the uri</param> public ODataUriBuilder(ODataUrlConventions urlConventions, ODataUri odataUri) { this.urlConventions = urlConventions; this.odataUri = odataUri; }