public void Can_deserialize_payload_with_primitive_parameters() { string actionName = "Primitive"; int quantity = 1; string productCode = "PCode"; string body = "{" + string.Format(@" ""Quantity"": {0} , ""ProductCode"": ""{1}"" ", quantity, productCode) + "}"; ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(body)); message.SetHeader("Content-Type", "application/json;odata=verbose"); IEdmModel model = GetModel(); ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), model); ODataActionPayloadDeserializer deserializer = new ODataActionPayloadDeserializer(new DefaultODataDeserializerProvider()); ODataPath path = CreatePath(model, actionName); ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = model }; ODataActionParameters payload = deserializer.Read(reader, context) as ODataActionParameters; Assert.NotNull(payload); Assert.Same( model.EntityContainers().Single().FunctionImports().SingleOrDefault(f => f.Name == "Primitive"), ODataActionPayloadDeserializer.GetFunctionImport(context)); Assert.True(payload.ContainsKey("Quantity")); Assert.Equal(quantity, payload["Quantity"]); Assert.True(payload.ContainsKey("ProductCode")); Assert.Equal(productCode, payload["ProductCode"]); }
/// <summary> /// Specifically use to query single entry or multi entries(query with $expand) /// </summary> /// <param name="requestUri"></param> /// <param name="mimeType"></param> /// <returns></returns> public List<ODataEntry> QueryEntries(string requestUri, string mimeType) { List<ODataEntry> entries = new List<ODataEntry>(); ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings() { BaseUri = baseUri }; var requestMessage = new HttpWebRequestMessage(new Uri(baseUri.AbsoluteUri + requestUri, UriKind.Absolute)); requestMessage.SetHeader("Accept", mimeType); var responseMessage = requestMessage.GetResponse(); Assert.AreEqual(200, responseMessage.StatusCode); if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata)) { using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, model)) { var reader = messageReader.CreateODataEntryReader(); while (reader.Read()) { if (reader.State == ODataReaderState.EntryEnd) { entries.Add(reader.Item as ODataEntry); } } Assert.AreEqual(ODataReaderState.Completed, reader.State); } } return entries; }
public void ReadJsonLight() { // Arrange var deserializer = new ODataEntityReferenceLinkDeserializer(); MockODataRequestMessage requestMessage = new MockODataRequestMessage(); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(); writerSettings.SetContentType(ODataFormat.Json); IEdmModel model = CreateModel(); ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, writerSettings, model); messageWriter.WriteEntityReferenceLink(new ODataEntityReferenceLink { Url = new Uri("http://localhost/samplelink") }); ODataMessageReader messageReader = new ODataMessageReader(new MockODataRequestMessage(requestMessage), new ODataMessageReaderSettings(), model); IEdmNavigationProperty navigationProperty = GetNavigationProperty(model); ODataDeserializerContext context = new ODataDeserializerContext { Request = new HttpRequestMessage(), Path = new ODataPath(new NavigationPathSegment(navigationProperty)) }; // Act Uri uri = deserializer.Read(messageReader, typeof(Uri), context) as Uri; // Assert Assert.NotNull(uri); Assert.Equal("http://localhost/samplelink", uri.AbsoluteUri); }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } if (readContext == null) { throw Error.ArgumentNull("readContext"); } if (readContext.Path == null) { throw Error.Argument("readContext", SRResources.ODataPathMissing); } IEdmEntitySet entitySet = GetEntitySet(readContext.Path); if (entitySet == null) { throw new SerializationException(SRResources.EntitySetMissingDuringDeserialization); } ODataReader odataReader = messageReader.CreateODataEntryReader(entitySet, EntityType.EntityDefinition()); ODataEntryWithNavigationLinks topLevelEntry = ReadEntryOrFeed(odataReader) as ODataEntryWithNavigationLinks; Contract.Assert(topLevelEntry != null); return ReadInline(topLevelEntry, readContext); }
protected override void ReadFromMessageReader(ODataMessageReader reader, IEdmTypeReference expectedType) { ODataProperty collectionProperty = reader.ReadProperty(expectedType); Type type = Nullable.GetUnderlyingType(base.ExpectedType) ?? base.ExpectedType; object obj2 = collectionProperty.Value; if (expectedType.IsCollection()) { object obj3; Type collectionItemType = type; Type implementationType = ClientTypeUtil.GetImplementationType(type, typeof(ICollection<>)); if (implementationType != null) { collectionItemType = implementationType.GetGenericArguments()[0]; obj3 = ODataMaterializer.CreateCollectionInstance(collectionProperty, type, base.ResponseInfo); } else { implementationType = typeof(ICollection<>).MakeGenericType(new Type[] { collectionItemType }); obj3 = ODataMaterializer.CreateCollectionInstance(collectionProperty, implementationType, base.ResponseInfo); } ODataMaterializer.ApplyCollectionDataValues(collectionProperty, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo, obj3, collectionItemType, ODataMaterializer.GetAddToCollectionDelegate(implementationType)); this.currentValue = obj3; } else if (expectedType.IsComplex()) { ODataComplexValue complexValue = obj2 as ODataComplexValue; ODataMaterializer.MaterializeComplexTypeProperty(type, complexValue, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo); this.currentValue = complexValue.GetMaterializedValue(); } else { ODataMaterializer.MaterializePrimitiveDataValue(base.ExpectedType, collectionProperty); this.currentValue = collectionProperty.GetMaterializedValue(); } }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } if (readContext == null) { throw Error.ArgumentNull("readContext"); } IEdmNavigationProperty navigationProperty = GetNavigationProperty(readContext.Path); if (navigationProperty == null) { throw new SerializationException(SRResources.NavigationPropertyMissingDuringDeserialization); } ODataEntityReferenceLink entityReferenceLink = messageReader.ReadEntityReferenceLink(navigationProperty); if (entityReferenceLink != null) { return ResolveContentId(entityReferenceLink.Url, readContext); } return null; }
private void ProcessUpdateEntityReference(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, ODataPath odataPath) { // This is for change the reference in single-valued navigation property // PUT ~/Person(0)/Parent/$ref // { // "@odata.context": "http://host/service/$metadata#$ref", // "@odata.id": "Orders(10643)" // } if (this.HttpMethod == HttpMethod.PATCH) { throw Utility.BuildException(HttpStatusCode.MethodNotAllowed, "PATCH on a reference link is not supported.", null); } // Get the parent first var level = this.QueryContext.QueryPath.Count - 2; var parent = this.QueryContext.ResolveQuery(this.DataSource, level); var navigationPropertyName = ((NavigationPropertyLinkSegment)odataPath.LastSegment).NavigationProperty.Name; using (var messageReader = new ODataMessageReader(requestMessage, this.GetReaderSettings(), this.DataSource.Model)) { var referenceLink = messageReader.ReadEntityReferenceLink(); var queryContext = new QueryContext(this.ServiceRootUri, referenceLink.Url, this.DataSource.Model); var target = queryContext.ResolveQuery(this.DataSource); this.DataSource.UpdateProvider.UpdateLink(parent, navigationPropertyName, target); this.DataSource.UpdateProvider.SaveChanges(); } ResponseWriter.WriteEmptyResponse(responseMessage); }
public void Can_deserialize_payload_with_complex_parameters() { string actionName = "Complex"; string body = @"{ ""Quantity"": 1 , ""Address"": { ""StreetAddress"":""1 Microsoft Way"", ""City"": ""Redmond"", ""State"": ""WA"", ""ZipCode"": 98052 } }"; ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(body)); message.SetHeader("Content-Type", "application/json;odata=verbose"); IEdmModel model = GetModel(); ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), model); ODataActionPayloadDeserializer deserializer = new ODataActionPayloadDeserializer(typeof(ODataActionParameters), new DefaultODataDeserializerProvider(model)); string url = "http://server/service/Customers(10)/" + actionName; HttpRequestMessage request = GetPostRequest(url); ODataDeserializerContext context = new ODataDeserializerContext { Request = request, Model = model }; ODataActionParameters payload = deserializer.Read(reader, context) as ODataActionParameters; Assert.NotNull(payload); Assert.Same(model.EntityContainers().Single().FunctionImports().SingleOrDefault(f => f.Name == "Complex"), payload.GetFunctionImport(context)); Assert.True(payload.ContainsKey("Quantity")); Assert.Equal(1, payload["Quantity"]); Assert.True(payload.ContainsKey("Address")); MyAddress address = payload["Address"] as MyAddress; Assert.NotNull(address); Assert.Equal("1 Microsoft Way", address.StreetAddress); Assert.Equal("Redmond", address.City); Assert.Equal("WA", address.State); Assert.Equal(98052, address.ZipCode); }
public async Task ModelBuilderTest() { string requestUri = string.Format("{0}/odata/$metadata", this.BaseAddress); HttpResponseMessage response = await this.Client.GetAsync(requestUri); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers); var reader = new ODataMessageReader(message); var edmModel = reader.ReadMetadataDocument(); var container = edmModel.EntityContainer; Assert.Equal("Container", container.Name); var employeeType = edmModel.SchemaElements.Single(e => e.Name == "Employee") as IEdmEntityType; employeeType.Properties().All(p => this.IsCamelCase(p.Name)); var managerType = edmModel.SchemaElements.Single(e => e.Name == "Manager") as IEdmEntityType; Assert.Equal(7, managerType.Properties().Count()); managerType.Properties().All(p => this.IsCamelCase(p.Name)); var addressType = edmModel.SchemaElements.Single(e => e.Name == "Address") as IEdmComplexType; addressType.Properties().All(p => this.IsCamelCase(p.Name)); }
public void ReadCompletedAsyncResponse() { string payload = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nOData-Version: 4.0\r\n\r\n{\"@odata.context\":\"http://host/service/$metadata#MySingleton\",\"Id\":1}"; var asyncReader = this.CreateAsyncReader(payload); var asyncResponse = asyncReader.CreateResponseMessage(); Assert.Equal(200, asyncResponse.StatusCode); Assert.Equal("application/json", asyncResponse.GetHeader("Content-Type")); Assert.Equal("4.0", asyncResponse.GetHeader("OData-Version")); using (var innerMessageReader = new ODataMessageReader(asyncResponse, new ODataMessageReaderSettings(), userModel)) { var reader = innerMessageReader.CreateODataEntryReader(); while (reader.Read()) { if (reader.State == ODataReaderState.EntryEnd) { ODataEntry entry = reader.Item as ODataEntry; Assert.Equal(1, entry.Properties.Single(p => p.Name == "Id").Value); } } } }
/// <inheritdoc /> public override object Read( ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { return enumDeserializer.Read(messageReader, type, readContext); }
public void CreateMessageReaderShouldSetAnnotationFilterWhenODataAnnotationIsSetOnPreferenceAppliedHeader() { IODataResponseMessage responseMessage = new InMemoryMessage(); responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings()); reader.Settings.ShouldIncludeAnnotation.Should().NotBeNull(); }
public void EntryMetadataUrlRoundTrip() { var stream = new MemoryStream(); var writerRequestMemoryMessage = new InMemoryMessage(); writerRequestMemoryMessage.Stream = stream; writerRequestMemoryMessage.SetHeader("Content-Type", "application/json"); var writerSettings = new ODataMessageWriterSettings() {Version = ODataVersion.V4, DisableMessageStreamDisposal = true}; writerSettings.ODataUri = new ODataUri() {ServiceRoot = new Uri("http://christro.svc/")}; var messageWriter = new ODataMessageWriter((IODataResponseMessage)writerRequestMemoryMessage, writerSettings, this.model); var organizationSetWriter = messageWriter.CreateODataEntryWriter(this.organizationsSet); var odataEntry = new ODataEntry(){ TypeName = ModelNamespace + ".Corporation" }; odataEntry.Property("Id", 1); odataEntry.Property("Name", ""); odataEntry.Property("TickerSymbol", "MSFT"); organizationSetWriter.WriteStart(odataEntry); organizationSetWriter.WriteEnd(); var readerPayloadInput = Encoding.UTF8.GetString(stream.GetBuffer()); Console.WriteLine(readerPayloadInput); var readerResponseMemoryMessage = new InMemoryMessage(); readerResponseMemoryMessage.Stream = new MemoryStream(stream.GetBuffer()); readerResponseMemoryMessage.SetHeader("Content-Type", "application/json"); var messageReader = new ODataMessageReader((IODataResponseMessage)readerResponseMemoryMessage, new ODataMessageReaderSettings() {MaxProtocolVersion = ODataVersion.V4, DisableMessageStreamDisposal = true}, this.model); var organizationReader = messageReader.CreateODataEntryReader(this.organizationsSet, this.organizationsSet.EntityType()); organizationReader.Read().Should().Be(true); organizationReader.Item.As<ODataEntry>(); }
public void ReadValueOfTypeDefinitionShouldWork() { Stream stream = new MemoryStream(Encoding.Default.GetBytes("123")); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel()); reader.ReadValue(new EdmTypeDefinitionReference(new EdmTypeDefinition("NS", "Length", EdmPrimitiveTypeKind.Int32), true)).Should().Be(123); }
public void ReadValueOfAbbreviativeDateShouldWork() { Stream stream = new MemoryStream(Encoding.Default.GetBytes("2014-1-3")); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel()); reader.ReadValue(new EdmTypeDefinitionReference(new EdmTypeDefinition("NS", "DateValue", EdmPrimitiveTypeKind.Date), true)).Should().Be(new Date(2014, 1, 3)); }
public async Task ModelBuilderTest(string modelMode) { string requestUri = string.Format("{0}/{1}/$metadata", this.BaseAddress, modelMode); HttpResponseMessage response = await this.Client.GetAsync(requestUri); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers); var reader = new ODataMessageReader(message); var edmModel = reader.ReadMetadataDocument(); var fileType = edmModel.SchemaElements.OfType<IEdmEntityType>().Single(et => et.Name == "File"); Assert.Equal(5, fileType.Properties().Count()); var createdDateProperty = fileType.DeclaredProperties.Single(p => p.Name == "CreatedDate"); Assert.Equal(EdmTypeKind.Primitive, createdDateProperty.Type.TypeKind()); Assert.Equal("Edm.DateTimeOffset", createdDateProperty.Type.Definition.FullTypeName()); Assert.False(createdDateProperty.Type.IsNullable); var deleteDateProperty = fileType.DeclaredProperties.Single(p => p.Name == "DeleteDate"); Assert.Equal(EdmTypeKind.Primitive, deleteDateProperty.Type.TypeKind()); Assert.Equal("Edm.DateTimeOffset", deleteDateProperty.Type.Definition.FullTypeName()); Assert.True(deleteDateProperty.Type.IsNullable); var modifiedDates = fileType.DeclaredProperties.Single(p => p.Name == "ModifiedDates"); Assert.Equal(EdmTypeKind.Collection, modifiedDates.Type.TypeKind()); Assert.Equal("Collection(Edm.DateTimeOffset)", modifiedDates.Type.Definition.FullTypeName()); Assert.False(modifiedDates.Type.IsNullable); }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmTypeReference edmType = readContext.GetEdmType(type); Contract.Assert(edmType != null); if (!edmType.IsCollection()) { throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Collection); } IEdmCollectionTypeReference collectionType = edmType.AsCollection(); IEdmTypeReference elementType = collectionType.ElementType(); IEnumerable result = ReadInline(ReadCollection(messageReader, elementType), edmType, readContext) as IEnumerable; if (result != null && readContext.IsUntyped && elementType.IsComplex()) { EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType); foreach (EdmComplexObject complexObject in result) { complexCollection.Add(complexObject); } return complexCollection; } return result; }
public async Task ReferentialConstraintModelBuilderTest(string modelMode) { string requestUri = string.Format("{0}/{1}/$metadata", this.BaseAddress, modelMode); HttpResponseMessage response = await this.Client.GetAsync(requestUri); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage message = new ODataMessageWrapper(stream, response.Content.Headers); var reader = new ODataMessageReader(message); var edmModel = reader.ReadMetadataDocument(); var customer = edmModel.SchemaElements.OfType<IEdmEntityType>() .Single(et => et.Name == "ForeignKeyCustomer"); Assert.Equal(3, customer.Properties().Count()); var order = edmModel.SchemaElements.OfType<IEdmEntityType>().Single(et => et.Name == "ForeignKeyOrder"); Assert.Equal(4, order.Properties().Count()); var customerIdProperty = order.DeclaredProperties.Single(p => p.Name == "CustomerId"); var navProperty = order.DeclaredNavigationProperties().Single(p => p.Name == "Customer"); Assert.Equal(EdmOnDeleteAction.Cascade, navProperty.OnDelete); Assert.Equal(1, navProperty.DependentProperties.Count()); var dependentProperty = navProperty.DependentProperties.Single(); Assert.Same(customerIdProperty, dependentProperty); }
public void EncodingShouldRemainInvariantInReader() { Stream stream = new MemoryStream(Encoding.GetEncoding("iso-8859-1").GetBytes("{\"@odata.context\":\"http://stuff/#Edm.Int32\",\"value\":4}")); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", "application/json;odata.metadata=minimal;"); ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel()); reader.ReadProperty(); }
public void CreateMessageReaderShouldNotSetAnnotationFilterWhenItIsAlreadySet() { IODataResponseMessage responseMessage = new InMemoryMessage(); responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; Func<string, bool> shouldWrite = name => false; ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings { ShouldIncludeAnnotation = shouldWrite }); reader.Settings.ShouldIncludeAnnotation.Should().BeSameAs(shouldWrite); }
protected sealed override void OnDispose() { if (this.messageReader != null) { this.messageReader.Dispose(); this.messageReader = null; } }
/// <summary> /// Constructor. /// </summary> /// <param name="messageReader">The message reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> /// <remarks> /// This constructor is used if not special checks against a test message should be performed. /// Use the constructor overload that takes a <see cref="TestMessage"/> argument to enforce checks /// around disposal of the message. /// </remarks> public ODataMessageReaderTestWrapper(ODataMessageReader messageReader, ODataMessageReaderSettings messageReaderSettings, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(messageReader, "messageReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.messageReader = messageReader; this.messageReaderSettings = messageReaderSettings; this.testConfiguration = testConfiguration; }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } ODataCollectionValue value = ReadCollection(messageReader); return ReadInline(value, readContext); }
internal ODataMessageReaderDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription, bool enableWcfDataServicesServerBehavior) : base(update, dataService, tracker, requestDescription) { System.Data.Services.ODataRequestMessage requestMessage = new System.Data.Services.ODataRequestMessage(dataService.OperationContext.Host); if (WebUtil.CompareMimeType(requestMessage.ContentType, "*/*")) { requestMessage.ContentType = "application/atom+xml"; } this.messageReader = new ODataMessageReader(requestMessage, WebUtil.CreateMessageReaderSettings(dataService, enableWcfDataServicesServerBehavior), dataService.Provider.GetMetadataModel(base.Service.OperationContext)); this.contentFormat = System.Data.Services.ContentFormat.Unknown; }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } ODataProperty property = messageReader.ReadProperty(); return ReadInline(property, readContext); }
public static IEdmModel GetServiceModel(Uri uri) { HttpWebRequestMessage message = new HttpWebRequestMessage(uri); message.SetHeader("Accept", MimeTypes.ApplicationXml); using (var messageReader = new ODataMessageReader(message.GetResponse())) { return messageReader.ReadMetadataDocument(); } }
public void ReadThrowsWhenPathIsMissing() { // Arrange var deserializer = new ODataEntityReferenceLinkDeserializer(); ODataMessageReader reader = new ODataMessageReader(new MockODataRequestMessage()); ODataDeserializerContext context = new ODataDeserializerContext(); // Act & Assert Assert.Throws<SerializationException>(() => deserializer.Read(reader, context), "The operation cannot be completed because no ODataPath is available for the request."); }
public override void CustomTestInitialize() { // retrieve IEdmModel of the test service HttpWebRequestMessage message = new HttpWebRequestMessage(new Uri(this.ServiceUri.AbsoluteUri + "$metadata", UriKind.Absolute)); message.SetHeader("Accept", MimeTypes.ApplicationXml); using (var messageReader = new ODataMessageReader(message.GetResponse())) { this.model = messageReader.ReadMetadataDocument(); } }
public ODataAdapter(ISession session, string protocolVersion, HttpResponseMessage response) : this(session, protocolVersion) { var readerSettings = new ODataMessageReaderSettings { MessageQuotas = { MaxReceivedMessageSize = Int32.MaxValue } }; using (var messageReader = new ODataMessageReader(new ODataResponseMessage(response), readerSettings)) { Model = messageReader.ReadMetadataDocument(); } }
public override object Read(ODataMessageReader messageReader, ODataDeserializerReadContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } object value = messageReader.ReadValue(PrimitiveTypeReference); // TODO: Bug 467612: do value conversions here. return value; }
public void ValidServiceDocument() { var metadataMessage = new HttpWebRequestMessage(new Uri(ServiceUri + "$metadata")); metadataMessage.SetHeader("Accept", MimeTypes.ApplicationXml); var metadataMessageReader = new ODataMessageReader(metadataMessage.GetResponse()); var model = metadataMessageReader.ReadMetadataDocument(); var message = new HttpWebRequestMessage(ServiceUri); message.SetHeader("Accept", MimeTypes.ApplicationJson); ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings() { BaseUri = ServiceUri }; using (var messageReader = new ODataMessageReader(message.GetResponse(), readerSettings, model)) { var workspace = messageReader.ReadServiceDocument(); Assert.Equal(21, workspace.EntitySets.Count(e => e.Name.StartsWith("EF"))); Assert.True(workspace.EntitySets.All(e => e.Name.StartsWith("EF"))); } }
public void Read_ReturnsEdmComplexObjectCollection_TypelessMode() { // Arrange HttpContent content = new StringContent("{ 'value': [ { 'City' : 'Redmond' } ] }"); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); IODataRequestMessage request = new ODataMessageWrapper(content.ReadAsStreamAsync().Result, content.Headers); ODataMessageReader reader = new ODataMessageReader(request, new ODataMessageReaderSettings(), _model); var deserializer = new ODataCollectionDeserializer(new DefaultODataDeserializerProvider()); ODataDeserializerContext readContext = new ODataDeserializerContext { Model = _model, ResourceType = typeof(IEdmObject), ResourceEdmType = _addressCollectionType }; // Act var result = deserializer.Read(reader, typeof(IEdmObject), readContext); // Assert IEdmObject edmObject = Assert.IsType <EdmComplexObjectCollection>(result); Assert.Equal(_addressCollectionType, edmObject.GetEdmType()); }
private void ReadEntryPayload(IEdmModel userModel, string payload, EdmEntitySet entitySet, IEdmEntityType entityType, Action <ODataReader> action, bool isIeee754Compatible = true) { var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; string contentType = isIeee754Compatible ? "application/json;odata.metadata=minimal;IEEE754Compatible=true" : "application/json;odata.metadata=minimal;IEEE754Compatible=false"; message.SetHeader("Content-Type", contentType); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false }; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, readerSettings, userModel)) { var reader = msgReader.CreateODataEntryReader(entitySet, entityType); while (reader.Read()) { action(reader); } } }
public async Task Read_ReturnsEdmComplexObjectCollection_TypelessMode() { // Arrange IEdmTypeReference addressType = _model.GetEdmTypeReference(typeof(Address)).AsComplex(); IEdmCollectionTypeReference addressCollectionType = new EdmCollectionTypeReference(new EdmCollectionType(addressType)); HttpContent content = new StringContent("{ 'value': [ {'@odata.type':'Microsoft.AspNet.OData.Test.Common.Models.Address', 'City' : 'Redmond' } ] }"); var headers = FormatterTestHelper.GetContentHeaders("application/json"); IODataRequestMessage request = ODataMessageWrapperHelper.Create(await content.ReadAsStreamAsync(), headers); ODataMessageReader reader = new ODataMessageReader(request, new ODataMessageReaderSettings(), _model); var deserializer = new ODataResourceSetDeserializer(_deserializerProvider); ODataDeserializerContext readContext = new ODataDeserializerContext { Model = _model, ResourceType = typeof(IEdmObject), ResourceEdmType = addressCollectionType }; // Act IEnumerable result = deserializer.Read(reader, typeof(IEdmObject), readContext) as IEnumerable; // Assert var addresses = result.Cast <EdmComplexObject>(); Assert.NotNull(addresses); EdmComplexObject address = Assert.Single(addresses); Assert.Equal(new[] { "City" }, address.GetChangedPropertyNames()); object city; Assert.True(address.TryGetPropertyValue("City", out city)); Assert.Equal("Redmond", city); }
public async Task CanHandleAutomicityGroupRequestsAndUngroupedRequest_JsonBatch() { // Arrange var requestUri = string.Format("{0}/DefaultBatch/$batch", this.BaseAddress); string absoluteUri = this.BaseAddress + "/DefaultBatch/DefaultBatchCustomer"; // Act HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json")); HttpContent content = new StringContent(@" { ""requests"": [{ ""id"": ""1"", ""atomicityGroup"": ""f7de7314-2f3d-4422-b840-ada6d6de0f18"", ""method"": ""POST"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Id"":11, ""Name"":""CreatedByJsonBatch_11"" } }, { ""id"": ""2"", ""atomicityGroup"": ""f7de7314-2f3d-4422-b840-ada6d6de0f18"", ""method"": ""POST"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Id"":12, ""Name"":""CreatedByJsonBatch_12"" } }, { ""id"": ""3"", ""method"": ""POST"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Id"":13, ""Name"":""CreatedByJsonBatch_3"" } } ] }"); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); request.Content = content; HttpResponseMessage response = await Client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage odataResponseMessage = new ODataMessageWrapper(stream, response.Content.Headers); int subResponseCount = 0; using (var messageReader = new ODataMessageReader(odataResponseMessage, new ODataMessageReaderSettings(), GetEdmModel(new ODataConventionModelBuilder()))) { var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: var operationMessage = batchReader.CreateOperationResponseMessage(); subResponseCount++; Assert.Equal(201, operationMessage.StatusCode); break; } } } Assert.Equal(3, subResponseCount); }
protected IEnumerable Read(Stream response, Db.OeEntitySetAdapter entitySetMetaAdatpter) { ResourceSet = null; NavigationProperties.Clear(); NavigationInfoEntities.Clear(); IODataResponseMessage responseMessage = new Infrastructure.OeInMemoryMessage(response, null, _serviceProvider); var settings = new ODataMessageReaderSettings() { EnableMessageStreamDisposal = false, Validations = ValidationKinds.None }; using (var messageReader = new ODataMessageReader(responseMessage, settings, EdmModel)) { IEdmEntitySet entitySet = OeEdmClrHelper.GetEntitySet(EdmModel, entitySetMetaAdatpter.EntitySetName); ODataReader reader = messageReader.CreateODataResourceSetReader(entitySet, entitySet.EntityType()); var stack = new Stack <StackItem>(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.ResourceSetStart: if (stack.Count == 0) { ResourceSet = (ODataResourceSetBase)reader.Item; } else { stack.Peek().ResourceSet = (ODataResourceSetBase)reader.Item; } break; case ODataReaderState.ResourceStart: stack.Push(new StackItem((ODataResource)reader.Item)); break; case ODataReaderState.ResourceEnd: StackItem stackItem = stack.Pop(); if (reader.Item != null) { if (stack.Count == 0) { yield return(CreateRootEntity((ODataResource)stackItem.Item, stackItem.NavigationProperties, entitySetMetaAdatpter.EntityType)); } else { stack.Peek().AddEntry(CreateEntity((ODataResource)stackItem.Item, stackItem.NavigationProperties)); } } break; case ODataReaderState.NestedResourceInfoStart: stack.Push(new StackItem((ODataNestedResourceInfo)reader.Item)); break; case ODataReaderState.NestedResourceInfoEnd: StackItem item = stack.Pop(); stack.Peek().AddLink((ODataNestedResourceInfo)item.Item, item.Value, item.ResourceSet); break; } } } }
public async Task CanContinueOnErrorWhenHeaderSet() { // Arrange var requestUri = string.Format("{0}/DefaultBatch/$batch", this.BaseAddress); string absoluteUri = this.BaseAddress + "/DefaultBatch/DefaultBatchCustomer"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("multipart/mixed")); request.Headers.Add("prefer", "odata.continue-on-error"); HttpContent content = new StringContent( @"--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0 Content-Type: application/http Content-Transfer-Encoding: binary GET " + absoluteUri + @"(0) HTTP/1.1 --batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0 Content-Type: application/http Content-Transfer-Encoding: binary GET " + absoluteUri + @"(-1) HTTP/1.1 --batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0 Content-Type: application/http Content-Transfer-Encoding: binary GET " + absoluteUri + @"(1) HTTP/1.1 --batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0-- "); content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/mixed; boundary=batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0"); request.Content = content; // Act HttpResponseMessage response = await Client.SendAsync(request); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage odataResponseMessage = new ODataMessageWrapper(stream, response.Content.Headers); int subResponseCount = 0; // Assert using (var messageReader = new ODataMessageReader(odataResponseMessage, new ODataMessageReaderSettings(), GetEdmModel(new ODataConventionModelBuilder()))) { var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: var operationMessage = batchReader.CreateOperationResponseMessage(); subResponseCount++; if (subResponseCount == 2) { Assert.Equal(500, operationMessage.StatusCode); } else { Assert.Equal(200, operationMessage.StatusCode); } break; } } } Assert.Equal(3, subResponseCount); }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmFunctionImport action = GetFunctionImport(readContext); // Create the correct resource type; Dictionary <string, object> payload; if (type == typeof(ODataActionParameters)) { payload = new ODataActionParameters(); } else { payload = new ODataUntypedActionParameters(action); } ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmFunctionParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataCollectionValue value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = DeserializerProvider.GetEdmTypeDeserializer(collectionType) as ODataCollectionDeserializer; payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); break; default: break; } } return(payload); }
internal static IList <TableResult> TableBatchOperationPostProcess(IList <TableResult> result, TableBatchOperation batch, RESTCommand <IList <TableResult> > cmd, HttpWebResponse resp, OperationContext ctx) { ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, cmd.ResponseStream), readerSettings)) { // create a reader ODataBatchReader reader = responseReader.CreateODataBatchReader(); // Initial => changesetstart if (reader.State == ODataBatchReaderState.Initial) { reader.Read(); } if (reader.State == ODataBatchReaderState.ChangesetStart) { // ChangeSetStart => Operation reader.Read(); } int index = 0; bool failError = false; bool failUnexpected = false; while (reader.State == ODataBatchReaderState.Operation) { TableOperation currentOperation = batch[index]; TableResult currentResult = new TableResult() { Result = currentOperation.Entity }; result.Add(currentResult); ODataBatchOperationResponseMessage mimePartResponseMessage = reader.CreateOperationResponseMessage(); currentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; // Validate Status Code if (currentOperation.OperationType == TableOperationType.Insert) { failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.Conflict; failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.Created; } else if (currentOperation.OperationType == TableOperationType.Retrieve) { if (mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound) { index++; // Operation => next reader.Read(); continue; } failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.OK; } else { failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound; failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.NoContent; } if (failError) { cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; throw new StorageException( cmd.CurrentResult, cmd.CurrentResult.ExtendedErrorInformation != null ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : SR.ExtendedErrorUnavailable, null) { IsRetryable = false }; } if (failUnexpected) { cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; string indexString = Convert.ToString(index); // Attempt to extract index of failing entity from extended error info if (cmd.CurrentResult.ExtendedErrorInformation != null && !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string tempIndex = TableRequest.ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult); if (!string.IsNullOrEmpty(tempIndex)) { indexString = tempIndex; } } throw new StorageException(cmd.CurrentResult, SR.UnexpectedResponseCodeForOperation + indexString, null) { IsRetryable = true }; } // Update etag if (!string.IsNullOrEmpty(mimePartResponseMessage.GetHeader("ETag"))) { currentResult.Etag = mimePartResponseMessage.GetHeader("ETag"); if (currentOperation.Entity != null) { currentOperation.Entity.ETag = currentResult.Etag; } } // Parse Entity if needed if (currentOperation.OperationType == TableOperationType.Retrieve || currentOperation.OperationType == TableOperationType.Insert) { ReadOdataEntity(currentResult, currentOperation, mimePartResponseMessage, ctx, readerSettings); } index++; // Operation => reader.Read(); } } return(result); }
public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { HttpActionDescriptor actionDescriptor = readContext.Request.GetActionDescriptor(); if (actionDescriptor != null && !actionDescriptor.GetCustomAttributes <ActionAttribute>().Any() && !actionDescriptor.GetCustomAttributes <CreateAttribute>().Any() && !actionDescriptor.GetCustomAttributes <UpdateAttribute>().Any() && !actionDescriptor.GetCustomAttributes <PartialUpdateAttribute>().Any()) { throw new InvalidOperationException($"{nameof(DefaultODataActionCreateUpdateParameterDeserializer)} is designed for odata actions|creates|updates|partialUpdates only"); } TypeInfo typeInfo = type.GetTypeInfo(); IDependencyResolver dependencyResolver = readContext.Request.GetOwinContext() .GetDependencyResolver(); ITimeZoneManager timeZoneManager = dependencyResolver.Resolve <ITimeZoneManager>(); string requestJsonBody = (string)readContext.Request.Properties["ContentStreamAsJson"]; using (StringReader jsonStringReader = new StringReader(requestJsonBody)) using (JsonTextReader requestJsonReader = new JsonTextReader(jsonStringReader)) { void Error(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e) { if (e.ErrorContext.Error is JsonSerializationException && e.ErrorContext.Error.Message.StartsWith("Could not find member ", StringComparison.InvariantCultureIgnoreCase)) { if (e.CurrentObject is IOpenType openDto) { openDto.Properties = openDto.Properties ?? new Dictionary <string, object>(); if (requestJsonReader.Read()) { openDto.Properties.Add((string)e.ErrorContext.Member, requestJsonReader.Value); } } e.ErrorContext.Handled = true; } } JsonSerializerSettings settings = DefaultJsonContentFormatter.DeSerializeSettings(); settings.Converters = new JsonConverter[] { _odataJsonDeserializerEnumConverter, _stringCorrectorsConverters, new ODataJsonDeSerializerDateTimeOffsetTimeZone(timeZoneManager) }; settings.MissingMemberHandling = MissingMemberHandling.Error; JsonSerializer deserilizer = JsonSerializer.Create(settings); deserilizer.Error += Error; try { object result = null; if (!typeof(Delta).GetTypeInfo().IsAssignableFrom(typeInfo)) { result = deserilizer.Deserialize(requestJsonReader, typeInfo); } else { List <string> changedPropNames = new List <string>(); using (JsonTextReader jsonReaderForGettingSchema = new JsonTextReader(new StringReader(requestJsonBody))) { while (jsonReaderForGettingSchema.Read()) { if (jsonReaderForGettingSchema.Value != null && jsonReaderForGettingSchema.TokenType == JsonToken.PropertyName) { changedPropNames.Add(jsonReaderForGettingSchema.Value.ToString()); } else { } } } TypeInfo dtoType = typeInfo.GetGenericArguments().ExtendedSingle("Finding dto type from delta").GetTypeInfo(); object modifiedDto = deserilizer.Deserialize(requestJsonReader, dtoType); Delta delta = (Delta)Activator.CreateInstance(typeInfo); if (modifiedDto is IOpenType openTypeDto && openTypeDto.Properties?.Any() == true) { delta.TrySetPropertyValue(nameof(IOpenType.Properties), openTypeDto); } foreach (string changedProp in changedPropNames.Where(p => p != nameof(IOpenType.Properties) && dtoType.GetProperty(p) != null)) { delta.TrySetPropertyValue(changedProp, dtoType.GetProperty(changedProp).GetValue(modifiedDto)); } result = delta; } return(result); } finally { deserilizer.Error -= Error; } } }
/// <summary>Returns the format used by the message reader for reading the payload.</summary> /// <returns>The format used by the messageReader for reading the payload.</returns> /// <param name="messageReader">The <see cref="T:Microsoft.OData.ODataMessageReader" /> to get the read format from.</param> /// <remarks>This method must only be called once reading has started. /// This means that a read method has been called on the <paramref name="messageReader"/> or that a reader (for entries, resource sets, collections, etc.) has been created. /// If the method is called prior to that it will throw.</remarks> public static ODataFormat GetReadFormat(ODataMessageReader messageReader) { ExceptionUtils.CheckArgumentNotNull(messageReader, "messageReader"); return(messageReader.GetFormat()); }
private byte[] ServiceReadAsyncBatchRequestAndWriteAsyncResponse(byte[] requestPayload) { IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(requestPayload) }; requestMessage.SetHeader("Content-Type", batchContentType); using (var messageReader = new ODataMessageReader(requestMessage, new ODataMessageReaderSettings { BaseUri = new Uri(serviceDocumentUri) }, this.userModel)) { var responseStream = new MemoryStream(); IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream }; responseMessage.SetHeader("Content-Type", batchContentType); var messageWriter = new ODataMessageWriter(responseMessage); var batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: // Encountered an operation (either top-level or in a changeset) var operationMessage = batchReader.CreateOperationRequestMessage(); if (operationMessage.Method == "GET" && operationMessage.Url.AbsolutePath.Contains("ALFKI")) { var response = batchWriter.CreateOperationResponseMessage(null); response.StatusCode = 200; response.SetHeader("Content-Type", "application/json;"); var settings = new ODataMessageWriterSettings(); settings.SetServiceDocumentUri(new Uri(serviceDocumentUri)); using (var operationMessageWriter = new ODataMessageWriter(response, settings, this.userModel)) { var entryWriter = operationMessageWriter.CreateODataResourceWriter(this.customers, this.customerType); var entry = new ODataResource() { TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty() { Name = "Id", Value = "ALFKI" }, new ODataProperty() { Name = "Name", Value = "John" } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); } } break; } } var asyncResponse = batchWriter.CreateOperationResponseMessage(null); asyncResponse.StatusCode = 202; asyncResponse.SetHeader("Location", "http://service/async-monitor"); asyncResponse.SetHeader("Retry-After", "10"); batchWriter.WriteEndBatch(); responseStream.Position = 0; return(responseStream.ToArray()); } }
public void UnsignedIntAndTypeDefinitionRoundtripJsonLightIntegrationTest() { var model = new EdmModel(); var uint16 = new EdmTypeDefinition("MyNS", "UInt16", EdmPrimitiveTypeKind.Double); var uint16Ref = new EdmTypeDefinitionReference(uint16, false); model.AddElement(uint16); model.SetPrimitiveValueConverter(uint16Ref, UInt16ValueConverter.Instance); var uint64 = new EdmTypeDefinition("MyNS", "UInt64", EdmPrimitiveTypeKind.String); var uint64Ref = new EdmTypeDefinitionReference(uint64, false); model.AddElement(uint64); model.SetPrimitiveValueConverter(uint64Ref, UInt64ValueConverter.Instance); var guidType = new EdmTypeDefinition("MyNS", "Guid", EdmPrimitiveTypeKind.Int64); var guidRef = new EdmTypeDefinitionReference(guidType, true); model.AddElement(guidType); var personType = new EdmEntityType("MyNS", "Person"); personType.AddKeys(personType.AddStructuralProperty("ID", uint64Ref)); personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String); personType.AddStructuralProperty("FavoriteNumber", uint16Ref); personType.AddStructuralProperty("Age", model.GetUInt32("MyNS", true)); personType.AddStructuralProperty("Guid", guidRef); personType.AddStructuralProperty("Weight", EdmPrimitiveTypeKind.Double); personType.AddStructuralProperty("Money", EdmPrimitiveTypeKind.Decimal); model.AddElement(personType); var container = new EdmEntityContainer("MyNS", "Container"); var peopleSet = container.AddEntitySet("People", personType); model.AddElement(container); var stream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage { Stream = stream }; message.StatusCode = 200; var writerSettings = new ODataMessageWriterSettings(); writerSettings.SetServiceDocumentUri(new Uri("http://host/service")); var messageWriter = new ODataMessageWriter(message, writerSettings, model); var entryWriter = messageWriter.CreateODataResourceWriter(peopleSet); var entry = new ODataResource { TypeName = "MyNS.Person", Properties = new[] { new ODataProperty { Name = "ID", Value = UInt64.MaxValue }, new ODataProperty { Name = "Name", Value = "Foo" }, new ODataProperty { Name = "FavoriteNumber", Value = (UInt16)250 }, new ODataProperty { Name = "Age", Value = (UInt32)123 }, new ODataProperty { Name = "Guid", Value = Int64.MinValue }, new ODataProperty { Name = "Weight", Value = 123.45 }, new ODataProperty { Name = "Money", Value = Decimal.MaxValue } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); entryWriter.Flush(); stream.Position = 0; StreamReader reader = new StreamReader(stream); string payload = reader.ReadToEnd(); Assert.Equal("{\"@odata.context\":\"http://host/service/$metadata#People/$entity\",\"ID\":\"18446744073709551615\",\"Name\":\"Foo\",\"FavoriteNumber\":250.0,\"Age\":123,\"Guid\":-9223372036854775808,\"Weight\":123.45,\"Money\":79228162514264337593543950335}", payload); #if NETCOREAPP1_1 stream = new MemoryStream(Encoding.GetEncoding(0).GetBytes(payload)); #else stream = new MemoryStream(Encoding.Default.GetBytes(payload)); #endif message = new InMemoryMessage { Stream = stream }; message.StatusCode = 200; var readerSettings = new ODataMessageReaderSettings(); var messageReader = new ODataMessageReader(message, readerSettings, model); var entryReader = messageReader.CreateODataResourceReader(peopleSet, personType); Assert.True(entryReader.Read()); var entryReaded = entryReader.Item as ODataResource; var propertiesReaded = entryReaded.Properties.ToList(); var propertiesGiven = entry.Properties.ToList(); Assert.Equal(propertiesReaded.Count, propertiesGiven.Count); for (int i = 0; i < propertiesReaded.Count; ++i) { Assert.Equal(propertiesReaded[i].Name, propertiesGiven[i].Name); Assert.Equal(propertiesReaded[i].Value.GetType(), propertiesGiven[i].Value.GetType()); Assert.Equal(propertiesReaded[i].Value, propertiesGiven[i].Value); } }
/// <summary> /// Parse the constant entity collection node. /// </summary> /// <param name="nodeIn">The input constant node.</param> /// <returns>The parsed object.</returns> private object ParseEntityCollection(ConstantNode nodeIn) { ODataMessageReaderSettings settings = new ODataMessageReaderSettings(); InMemoryMessage message = new InMemoryMessage() { Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(nodeIn.LiteralText)), }; var entityType = ((nodeIn.TypeReference.Definition as IEdmCollectionType).ElementType as IEdmEntityTypeReference) .Definition as IEdmEntityType; object list = null; MethodInfo addMethod = null; using ( ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, settings, this.UriParser.Model)) { if (nodeIn.LiteralText.Contains("@odata.id")) { ODataEntityReferenceLinks referenceLinks = reader.ReadEntityReferenceLinks(); foreach (var referenceLink in referenceLinks.Links) { var queryContext = new QueryContext(this.UriParser.ServiceRoot, referenceLink.Url, this.DataSource.Model); var target = queryContext.ResolveQuery(this.DataSource); if (list == null) { // create the list. This would require the first type is not derived type. Type listType = typeof(List <>).MakeGenericType(target.GetType()); addMethod = listType.GetMethod("Add"); list = Activator.CreateInstance(listType); } addMethod.Invoke(list, new[] { target }); } return(list); } var feedReader = reader.CreateODataFeedReader( new EdmEntitySet(new EdmEntityContainer("NS", "Test"), "TestType", entityType), entityType); ODataEntry entry = null; while (feedReader.Read()) { if (feedReader.State == ODataReaderState.EntryEnd) { entry = feedReader.Item as ODataEntry; object item = ODataObjectModelConverter.ConvertPropertyValue(entry); if (list == null) { // create the list. This would require the first type is not derived type. var type = EdmClrTypeUtils.GetInstanceType(entry.TypeName); Type listType = typeof(List <>).MakeGenericType(type); addMethod = listType.GetMethod("Add"); list = Activator.CreateInstance(listType); } addMethod.Invoke(list, new[] { item }); } } return(list); } }
public void CreateMessageReaderShouldNotSetAnnotationFilterWhenODataAnnotationsIsNotSetOnPreferenceAppliedHeader() { ODataMessageReader reader = new ODataMessageReader((IODataResponseMessage) new InMemoryMessage(), new ODataMessageReaderSettings()); reader.Settings.ShouldIncludeAnnotation.Should().BeNull(); }
public async Task CanReadDataInBatchUsingEndpointRouting() { // Arrange var requestUri = string.Format("{0}/odata/$batch", this.BaseAddress); Uri address = new Uri(this.BaseAddress, UriKind.Absolute); string relativeToServiceRootUri = "EpCustomers"; string relativeToHostUri = address.LocalPath.TrimEnd(new char[] { '/' }) + "/odata/EpCustomers"; string absoluteUri = this.BaseAddress + "/odata/EpCustomers"; // Act HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json")); HttpContent content = new StringContent(@" { ""requests"":[ { ""id"": ""2"", ""method"": ""get"", ""url"": """ + relativeToServiceRootUri + @""", ""headers"": { ""Accept"": ""application/json""} }, { ""id"": ""3"", ""method"": ""get"", ""url"": """ + relativeToHostUri + @""" }, { ""id"": ""4"", ""method"": ""get"", ""url"": """ + absoluteUri + @""", ""headers"": { ""Accept"": ""application/json""} } ] }"); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); request.Content = content; HttpResponseMessage response = await Client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage odataResponseMessage = new ODataMessageWrapper(stream, response.Content.Headers); int subResponseCount = 0; var model = EdmModel; using (var messageReader = new ODataMessageReader(odataResponseMessage, new ODataMessageReaderSettings(), model)) { var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: var operationMessage = batchReader.CreateOperationResponseMessage(); subResponseCount++; Assert.Equal(200, operationMessage.StatusCode); Assert.Contains("application/json", operationMessage.Headers.Single(h => String.Equals(h.Key, "Content-Type", StringComparison.OrdinalIgnoreCase)).Value); using (var innerMessageReader = new ODataMessageReader(operationMessage, new ODataMessageReaderSettings(), model)) { var innerReader = innerMessageReader.CreateODataResourceSetReader(); while (innerReader.Read()) { ; } } break; } } } Assert.Equal(3, subResponseCount); }