public void ReadFromMessageReaderAndVerifyPayload(string payload, string contentType, Action <ODataMessageReader> readerAction) { var settings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false }; // with model { IODataResponseMessage message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader(ODataConstants.ContentTypeHeader, contentType); using (ODataMessageReader reader = new ODataMessageReader(message, settings, this.userModel)) { readerAction(reader); } } // without model should fail Action action = () => { IODataResponseMessage message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader(ODataConstants.ContentTypeHeader, contentType); message.SetHeader(ODataConstants.ContentTypeHeader, contentType); using (ODataMessageReader reader = new ODataMessageReader(message, settings)) { readerAction(reader); } }; action.ShouldThrow <ODataException>(); }
private ODataAsynchronousReader CreateAsyncReader() { IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream }; responseMessage.SetHeader("Content-Type", "application/http"); responseMessage.SetHeader("Content-Transfer-Encoding", "binary"); var messageReader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), userModel); return(messageReader.CreateODataAsynchronousReader()); }
private void CreateMessageReader(string payloadBody, bool forEntry, bool isResponse, bool enableReadingODataAnnotationWithoutPrefix) { string payloadPrefix = @"{ ""@odata.context"":""http://example.com/$metadata#EntitySet" + (forEntry ? "/$entity" : string.Empty) + "\","; const string payloadSuffix = "}"; string payload = payloadPrefix + payloadBody + payloadSuffix; var container = ContainerBuilderHelper.BuildContainer(null); container.GetRequiredService <ODataSimplifiedOptions>().EnableReadingODataAnnotationWithoutPrefix = enableReadingODataAnnotationWithoutPrefix; var message = new InMemoryMessage() { Container = container }; message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal;odata.streaming=true"); var messageSettings = new ODataMessageReaderSettings(); if (isResponse) { this.messageReader = new ODataMessageReader((IODataResponseMessage)message, messageSettings, this.model); } else { this.messageReader = new ODataMessageReader((IODataRequestMessage)message, messageSettings, this.model); } }
public void ShouldBeAbleToReadCustomInstanceAnnotationFromErrorInJsonLight() { const string payload = "{" + "\"error\":{" + "\"code\":\"400\"," + "\"message\":\"Resource not found for the segment 'Address'.\"," + "\"@instance.annotation\":\"stringValue\"" + "}" + "}"; var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); // Read instance annotations var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false }; IODataResponseMessage messageToRead = new InMemoryMessage { StatusCode = 400, Stream = stream }; messageToRead.SetHeader("Content-Type", "application/json;odata.streaming=true"); using (var messageReader = new ODataMessageReader(messageToRead, readerSettings, Model)) { ODataError error = messageReader.ReadError(); error.InstanceAnnotations.Should().HaveCount(1).And.Contain(ia => ia.Name == "instance.annotation"); } }
public void GetHeaderGoesToInnerMessageAfterLaterInnerSetHeaderCall() { const string headerName = "CustomHeaderName"; const string headerValueBefore = "CustomerHeaderValueBefore"; const string headerValueAfter = "CustomerHeaderValueAfter"; var simulatedRequestMessage = new InMemoryMessage(); simulatedRequestMessage.SetHeader(headerName, headerValueBefore); var odataRequestMessage = new ODataRequestMessage(simulatedRequestMessage, false, false, -1); simulatedRequestMessage.SetHeader(headerName, headerValueAfter); odataRequestMessage.GetHeader(headerName).Should().Be(headerValueAfter); }
public void ErrorLocationReportedByMessageReaderForBadEdmxOfSingleLineShouldBeAbsolute() { Stream stream = new MemoryStream(Encoding.UTF8.GetBytes( "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<!--Remark-->" + "<edmx:Edmx xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\" Version=\"4.0\">" + "<edmx:DataServices>" + "<Schema xmlns=\"http://docs.oasis-open.org/odata/ns/edm\" Namespace=\"Org.OData.Core.V1\" Alias=\"Core\">" + "<Annotation Term=\"Core.Description\">" + "<String>Core terms needed to write vocabularies</String>" + "</Annotation>" + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>")); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", "application/xml"); ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel()); const string expectedErrorMessage = "The metadata document could not be read from the message content.\r\n" + "UnexpectedXmlElement : The schema element 'Annotation' was not expected in the given context. : (1, 250)\r\n"; Action test = () => reader.ReadMetadataDocument(); test.ShouldThrow <ODataException>().WithMessage(expectedErrorMessage, ComparisonMode.Exact); }
public void StreamEncodingRemainsInvariant() { var settings = new ODataMessageWriterSettings { JsonPCallback = "functionName", EnableMessageStreamDisposal = false }; settings.SetServiceDocumentUri(new Uri("http://stuff")); StreamWriter streamWriter = new StreamWriter(new MemoryStream(), Encoding.GetEncoding("iso-8859-1")); IODataResponseMessage message = new InMemoryMessage { StatusCode = 200, Stream = streamWriter.BaseStream }; message.SetHeader("Content-Type", "application/json"); var property = new ODataProperty { Name = "PropertyName", Value = "value" }; using (var writer = new ODataMessageWriter(message, settings)) { writer.WriteProperty(property); } var responseStream = message.GetStream(); responseStream.Position = 0; var responseString = new StreamReader(responseStream, Encoding.GetEncoding("iso-8859-1")).ReadToEnd(); Assert.Equal("functionName({\"@odata.context\":\"http://stuff/$metadata#Edm.String\",\"value\":\"value\"})", responseString); Assert.StartsWith("text/javascript", message.GetHeader("Content-Type")); }
public void JsonPaddingEnabledWithUserSpecifiedContentType() { var settings = new ODataMessageWriterSettings { JsonPCallback = "functionName", EnableMessageStreamDisposal = false }; settings.SetServiceDocumentUri(new Uri("http://stuff")); IODataResponseMessage message = new InMemoryMessage { StatusCode = 200, Stream = new MemoryStream() }; message.SetHeader("Content-Type", "application/json"); var property = new ODataProperty { Name = "PropertyName", Value = "value" }; using (var writer = new ODataMessageWriter(message, settings)) { writer.WriteProperty(property); } var responseStream = message.GetStream(); responseStream.Position = 0; var responseString = new StreamReader(responseStream).ReadToEnd(); responseString.Should().Be("functionName({\"@odata.context\":\"http://stuff/$metadata#Edm.String\",\"value\":\"value\"})"); message.GetHeader("Content-Type").Should().StartWith("text/javascript"); }
private string WriterEntry(EdmModel userModel, ODataEntry entry, IEdmEntityType entityType) { var message = new InMemoryMessage() { Stream = new MemoryStream() }; message.SetHeader("Content-Type", "application/atom+xml;type=entry"); var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, EnableAtom = true }; writerSettings.SetServiceDocumentUri(ServiceDocumentUri); using (var msgReader = new ODataMessageWriter((IODataResponseMessage)message, writerSettings, userModel)) { var writer = msgReader.CreateODataEntryWriter(); writer.WriteStart(entry); writer.WriteEnd(); } message.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(message.Stream)) { return(reader.ReadToEnd()); } }
private static IList <ODataResource> GetReadedResourceWithNestedInfo(string messageContent, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType, IServiceProvider container) { var outputStream = new MemoryStream(); var writer = new StreamWriter(outputStream); writer.Write(messageContent); writer.Flush(); outputStream.Seek(0, SeekOrigin.Begin); IODataResponseMessage message = new InMemoryMessage { Stream = outputStream, Container = container }; message.SetHeader("Content-Type", "application/json;odata.metadata=full"); var settings = new ODataMessageReaderSettings(); using (var messageReader = new ODataMessageReader(message, settings, model)) { var reader = messageReader.CreateODataResourceReader(entitySet, entityType); IList <ODataResource> resources = new List <ODataResource>(); while (reader.Read()) { if (reader.State == ODataReaderState.ResourceEnd) { resources.Add(reader.Item as ODataResource); } } return(resources); } }
private static ODataResource GetReadedResource(string messageContent, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType, IServiceProvider container) { var outputStream = new MemoryStream(); var writer = new StreamWriter(outputStream); writer.Write(messageContent); writer.Flush(); outputStream.Seek(0, SeekOrigin.Begin); IODataResponseMessage message = new InMemoryMessage { Stream = outputStream, Container = container }; message.SetHeader("Content-Type", "application/json"); var settings = new ODataMessageReaderSettings(); using (var messageReader = new ODataMessageReader(message, settings, model)) { var reader = messageReader.CreateODataResourceReader(entitySet, entityType); Assert.True(reader.Read()); return(reader.Item as ODataResource); } }
private IList <ODataEntry> ReadJsonLightFeed(string payload, string contentType, bool readingResponse) { InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", contentType); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); IList <ODataEntry> entries = new List <ODataEntry>(); using (var messageReader = readingResponse ? new ODataMessageReader((IODataResponseMessage)message, null, Model) : new ODataMessageReader((IODataRequestMessage)message, null, Model)) { var reader = messageReader.CreateODataFeedReader(EntitySet, EntityType); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryEnd: entries.Add((ODataEntry)reader.Item); break; } } } return(entries); }
private bool ReadBatch(string requestPayload, ODataVersion version) { IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(requestPayload)) }; requestMessage.SetHeader("Content-Type", batchContentTypeMultipartMime); ODataMessageReaderSettings settings = new ODataMessageReaderSettings { Version = version }; using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, settings, this.userModel)) { ODataBatchReader batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: // Encountered an operation (either top-level or in a change set) ODataBatchOperationRequestMessage operationMessage = batchReader.CreateOperationRequestMessage(); break; } } } return(true); }
private ODataEntry ReadJsonLightEntry(string payload, string contentType, bool readingResponse) { InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", contentType); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); ODataEntry topLevelEntry = null; using (var messageReader = readingResponse ? new ODataMessageReader((IODataResponseMessage)message, null, Model) : new ODataMessageReader((IODataRequestMessage)message, null, Model)) { var reader = messageReader.CreateODataEntryReader(EntitySet, EntityType); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryEnd: topLevelEntry = (ODataEntry)reader.Item; break; } } } return(topLevelEntry); }
private IEdmModel ReadMetadataDocument(Dictionary <string, string> map, string mainUrl) { Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(map[mainUrl])); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", "application/xml"); ODataMessageReader reader = new ODataMessageReader(responseMessage); return(reader.ReadMetadataDocument((uri) => { string uriStr = uri.ToString(); if (map.ContainsKey(uriStr)) { #if NETCOREAPP1_1 return XmlReader.Create(new StringReader(map[uriStr])); #else return new XmlTextReader(new StringReader(map[uriStr])); #endif } return null; })); }
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>(); }
private static ODataMessageReader CreateODataMessageReader(string payload, string contentType, bool isResponse, bool shouldReadAndValidateCustomInstanceAnnotations, bool odataSimplified = false) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true, ODataSimplified = odataSimplified }; ODataMessageReader messageReader; if (isResponse) { IODataResponseMessage responseMessage = new InMemoryMessage { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", contentType); if (shouldReadAndValidateCustomInstanceAnnotations) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; } messageReader = new ODataMessageReader(responseMessage, readerSettings, Model); } else { IODataRequestMessage requestMessage = new InMemoryMessage { Method = "GET", Stream = stream }; requestMessage.SetHeader("Content-Type", contentType); readerSettings.ShouldIncludeAnnotation = shouldReadAndValidateCustomInstanceAnnotations ? ODataUtils.CreateAnnotationFilter("*") : null; messageReader = new ODataMessageReader(requestMessage, readerSettings, Model); } return(messageReader); }
private void ReadEntryPayload(IEdmModel userModel, string payload, EdmEntitySet entitySet, IEdmEntityType entityType, Action <ODataReader> action, bool isIeee754Compatible = true, IServiceProvider container = null) { var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)), Container = container }; 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 { EnableMessageStreamDisposal = true }; readerSettings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, readerSettings, userModel)) { var reader = msgReader.CreateODataResourceReader(entitySet, entityType); while (reader.Read()) { action(reader); } } }
private string GetWriterOutputForContentTypeAndKnobValue(ODataEntry entry, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType) { MemoryStream outputStream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream }; message.SetHeader("Content-Type", "application/json;odata.metadata=full"); ODataMessageWriterSettings settings = new ODataMessageWriterSettings() { AutoComputePayloadMetadataInJson = true, }; settings.SetServiceDocumentUri(new Uri("http://example.com")); string output; using (var messageWriter = new ODataMessageWriter(message, settings, model)) { ODataWriter writer = messageWriter.CreateODataEntryWriter(entitySet, entityType); writer.WriteStart(entry); writer.WriteEnd(); outputStream.Seek(0, SeekOrigin.Begin); output = new StreamReader(outputStream).ReadToEnd(); } return(output); }
private string SerializeEntryInFullMetadataJson( bool useKeyAsSegment, IEdmModel edmModel, IEdmEntityType entityType = null, IEdmEntitySet entitySet = null) { var settings = new ODataMessageWriterSettings { }; settings.SetServiceDocumentUri(new Uri("http://example.com/")); var outputStream = new MemoryStream(); var container = ContainerBuilderHelper.BuildContainer(null); container.GetRequiredService <ODataSimplifiedOptions>().EnableWritingKeyAsSegment = useKeyAsSegment; var responseMessage = new InMemoryMessage { Stream = outputStream, Container = container }; responseMessage.SetHeader("Content-Type", "application/json;odata.metadata=full"); string output; using (var messageWriter = new ODataMessageWriter((IODataResponseMessage)responseMessage, settings, edmModel)) { var entryWriter = messageWriter.CreateODataResourceWriter(entitySet, entityType); ODataProperty keyProperty = new ODataProperty() { Name = "Key", Value = "KeyValue" }; var entry = new ODataResource { Properties = new[] { keyProperty }, TypeName = "Namespace.Person" }; if (edmModel == null) { keyProperty.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }); entry.SetSerializationInfo(new ODataResourceSerializationInfo { NavigationSourceEntityTypeName = "Namespace.Person", NavigationSourceName = "People", ExpectedTypeName = "Namespace.Person", NavigationSourceKind = EdmNavigationSourceKind.EntitySet }); } entryWriter.WriteStart(entry); entryWriter.WriteEnd(); entryWriter.Flush(); outputStream.Seek(0, SeekOrigin.Begin); output = new StreamReader(outputStream).ReadToEnd(); } return(output); }
private string SerializeEntryInFullMetadataJson( bool?useKeyAsSegment, IEdmModel edmModel, IEdmEntityType entityType = null, IEdmEntitySet entitySet = null) { var settings = new ODataMessageWriterSettings { AutoComputePayloadMetadataInJson = true, UseKeyAsSegment = useKeyAsSegment, }; settings.SetServiceDocumentUri(new Uri("http://example.com/")); var outputStream = new MemoryStream(); var responseMessage = new InMemoryMessage { Stream = outputStream }; responseMessage.SetHeader("Content-Type", "application/json;odata.metadata=full"); string output; using (var messageWriter = new ODataMessageWriter((IODataResponseMessage)responseMessage, settings, edmModel)) { var entryWriter = messageWriter.CreateODataEntryWriter(entitySet, entityType); ODataProperty keyProperty = new ODataProperty() { Name = "Key", Value = "KeyValue" }; var entry = new ODataEntry { Properties = new[] { keyProperty }, TypeName = "Namespace.Person" }; if (edmModel == null) { keyProperty.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }); entry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceEntityTypeName = "Namespace.Person", NavigationSourceName = "People", ExpectedTypeName = "Namespace.Person" }); } entryWriter.WriteStart(entry); entryWriter.WriteEnd(); entryWriter.Flush(); outputStream.Seek(0, SeekOrigin.Begin); output = new StreamReader(outputStream).ReadToEnd(); } return(output); }
public void ReadMetadataDocumentShouldIncludeConverterForDefaultUnsignedIntImplementation() { Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8""?> <!--Remark--> <edmx:Edmx xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"" Version=""4.0""> <edmx:DataServices> <Schema xmlns=""http://docs.oasis-open.org/odata/ns/edm"" Namespace=""MyNS""> <TypeDefinition Name=""UInt16"" UnderlyingType=""Edm.Int32"" /> <TypeDefinition Name=""UInt32"" UnderlyingType=""Edm.Decimal"" /> <TypeDefinition Name=""UInt64"" UnderlyingType=""Edm.Decimal"" /> <EntityType Name=""Person""> <Key> <PropertyRef Name=""Id"" /> </Key> <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" /> <Property Name=""UInt16"" Type=""MyNS.UInt16"" Nullable=""false"" /> <Property Name=""UInt32"" Type=""MyNS.UInt32"" Nullable=""false"" /> <Property Name=""UInt64"" Type=""MyNS.UInt64"" Nullable=""false"" /> </EntityType> </Schema> </edmx:DataServices> </edmx:Edmx>")); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", "application/xml"); ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel()); var model = reader.ReadMetadataDocument(); var personType = model.FindDeclaredType("MyNS.Person") as IEdmEntityType; Assert.IsNotNull(personType); var uint16Type = personType.FindProperty("UInt16").Type; var uint32Type = personType.FindProperty("UInt32").Type; var uint64Type = personType.FindProperty("UInt64").Type; var uint16Converter = model.GetPrimitiveValueConverter(uint16Type.AsTypeDefinition()); var uint32Converter = model.GetPrimitiveValueConverter(uint32Type.AsTypeDefinition()); var uint64Converter = model.GetPrimitiveValueConverter(uint64Type.AsTypeDefinition()); Assert.AreEqual(Type.GetTypeCode(uint16Converter.ConvertToUnderlyingType((UInt16)123).GetType()), TypeCode.Int32); Assert.AreEqual(Type.GetTypeCode(uint32Converter.ConvertToUnderlyingType((UInt32)123).GetType()), TypeCode.UInt32); Assert.AreEqual(Type.GetTypeCode(uint64Converter.ConvertToUnderlyingType((UInt64)123).GetType()), TypeCode.Decimal); Assert.AreEqual(Type.GetTypeCode(uint16Converter.ConvertFromUnderlyingType(123).GetType()), TypeCode.UInt16); Assert.AreEqual(Type.GetTypeCode(uint32Converter.ConvertFromUnderlyingType((Int64)123).GetType()), TypeCode.Int64); Assert.AreEqual(Type.GetTypeCode(uint64Converter.ConvertFromUnderlyingType((Decimal)123).GetType()), TypeCode.UInt64); }
private byte[] ClientWriteAsyncBatchRequest() { var stream = new MemoryStream(); IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream }; requestMessage.SetHeader("Content-Type", batchContentType); using (var messageWriter = new ODataMessageWriter(requestMessage)) { var batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); // Write a query operation. var queryOperationMessage = batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), /*contentId*/ null); // Write a changeset with multi update operation. batchWriter.WriteStartChangeset(); // Create a creation operation in the changeset. var updateOperationMessage = batchWriter.CreateOperationRequestMessage("POST", new Uri(serviceDocumentUri + "/Customers"), "1"); // Use a new message writer to write the body of this operation. using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage)) { var entryWriter = operationMessageWriter.CreateODataEntryWriter(); var entry = new ODataEntry() { TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty() { Name = "Id", Value = "AFKIL" }, new ODataProperty() { Name = "Name", Value = "Bob" } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); } updateOperationMessage = batchWriter.CreateOperationRequestMessage("PATCH", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), "2"); using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage)) { var entryWriter = operationMessageWriter.CreateODataEntryWriter(); var entry = new ODataEntry() { TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty() { Name = "Name", Value = "Jack" } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); } batchWriter.WriteEndChangeset(); // Write a query operation. batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Products"), /*contentId*/ null); batchWriter.WriteEndBatch(); stream.Position = 0; return stream.ToArray(); } }
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(); }
protected virtual InMemoryMessage CreateRequestMessage(DataServiceClientRequestMessageArgs requestMessageArgs) { var requestMessage = new InMemoryMessage { Url = requestMessageArgs.RequestUri, Method = requestMessageArgs.Method, Stream = new MemoryStream() }; foreach (var header in requestMessageArgs.Headers) { requestMessage.SetHeader(header.Key, header.Value); } return(requestMessage); }
public void GetAcceptHeaderWithInnerValueGetsInnerValue() { const string headerName = "Accept"; const string headerValue = "json-rox"; var simulatedRequestMessage = new InMemoryMessage(); simulatedRequestMessage.SetHeader(headerName, headerValue); var odataRequestMessage = new ODataRequestMessage(simulatedRequestMessage, false, false, -1); odataRequestMessage.GetHeader(headerName).Should().Be(headerValue); }
private static ODataMessageWriter CreateODataMessageWriter(IEdmModel model, string contentType) { var settings = new ODataMessageWriterSettings { EnableMessageStreamDisposal = false, Version = ODataVersion.V4 }; settings.SetServiceDocumentUri(new Uri("http://example.com")); var message = new InMemoryMessage(); message.Stream = new MemoryStream(); message.SetHeader("Accept", contentType); message.SetHeader("Content-Type", contentType); message.SetHeader("OData-Version", "4.0"); if (model == null) { return(new ODataMessageWriter((IODataRequestMessage)message, settings)); } else { return(new ODataMessageWriter((IODataRequestMessage)message, settings, model)); } }
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, EnableMessageStreamDisposal = false }; writerSettings.ODataUri = new ODataUri() { ServiceRoot = new Uri("http://christro.svc/") }; var messageWriter = new ODataMessageWriter((IODataResponseMessage)writerRequestMemoryMessage, writerSettings, this.model); var organizationSetWriter = messageWriter.CreateODataResourceWriter(this.organizationsSet); var odataEntry = new ODataResource() { 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, EnableMessageStreamDisposal = false }, this.model); var organizationReader = messageReader.CreateODataResourceReader(this.organizationsSet, this.organizationsSet.EntityType()); organizationReader.Read().Should().Be(true); organizationReader.Item.As <ODataResource>(); }
public void SetHeaderIsNotAllowedWhenReading() { const string headerName = "CustomHeaderName"; const string headerValueBefore = "CustomerHeaderValueBefore"; const string headerValueAfter = "CustomerHeaderValueAfter"; var simulatedRequestMessage = new InMemoryMessage(); simulatedRequestMessage.SetHeader(headerName, headerValueBefore); var odataRequestMessage = new ODataRequestMessage(simulatedRequestMessage, false, false, -1); Action setHeader = (() => odataRequestMessage.SetHeader(headerName, headerValueAfter)); setHeader.ShouldThrow <ODataException>().WithMessage(Strings.ODataMessage_MustNotModifyMessage); }
private byte[] ClientWriteBatchRequest(BodyContentType bodyContentType) { MemoryStream stream = new MemoryStream(); IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream }; requestMessage.SetHeader(ODataConstants.ContentTypeHeader, batchContentTypeApplicationJson); using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage)) { ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); // Write a change set with update operation. batchWriter.WriteStartChangeset(); // Create an update operation in the change set. ODataBatchOperationRequestMessage updateOperationMessage = batchWriter.CreateOperationRequestMessage( "PUT", new Uri(serviceDocumentUri + "MyBlob"), "1"); // Set the content type with explicit character set so that the content string // is flushed into the operation message body stream without byte-order-mark. updateOperationMessage.SetHeader("CoNtEnt-TYPE", GetContentType(bodyContentType)); // Use the message writer to write encoded string content. using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(updateOperationMessage)) { operationMessageWriter.WriteValue(GetEncodedContentObject(bodyContentType, /*forRequest*/ true)); } batchWriter.WriteEndChangeset(); // Write a query operation. ODataBatchOperationRequestMessage queryOperationMessage = batchWriter.CreateOperationRequestMessage( "GET", new Uri(serviceDocumentUri + "MyBlob"), /*contentId*/ null); // Header modification on inner payload. queryOperationMessage.SetHeader("AcCePt", GetContentType(bodyContentType)); batchWriter.WriteEndBatch(); stream.Position = 0; return(stream.ToArray()); } }
private void ClientReadSingletonBatchResponse(byte[] responsePayload, string batchContentType) { IODataResponseMessage responseMessage = new InMemoryMessage() { Stream = new MemoryStream(responsePayload) }; responseMessage.SetHeader("Content-Type", batchContentType); using (ODataMessageReader messageReader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), this.userModel)) { ODataBatchReader batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: // Encountered an operation (either top-level or in a change set) ODataBatchOperationResponseMessage operationMessage = batchReader.CreateOperationResponseMessage(); if (operationMessage.StatusCode == 200) { using (ODataMessageReader innerMessageReader = new ODataMessageReader(operationMessage, new ODataMessageReaderSettings(), this.userModel)) { ODataReader reader = innerMessageReader.CreateODataResourceReader(); while (reader.Read()) { if (reader.State == ODataReaderState.ResourceEnd) { ODataResource entry = reader.Item as ODataResource; Assert.Equal(10, entry.Properties.Single(p => p.Name == "WebId").Value); Assert.Equal("WebSingleton", entry.Properties.Single(p => p.Name == "Name").Value); } } } // The only two messages with HTTP-200 response codes are the two GET requests with content id value of null. // Verify that: for multipart batch the content id of the response is matching that of the request; // for Json batch the content id of the response is not null. Assert.True( (batchReader is ODataJsonLightBatchReader && operationMessage.ContentId != null) || (batchReader is ODataMultipartMixedBatchReader && operationMessage.ContentId == null)); } break; } } } }
private void ClientReadBatchResponse(byte[] responsePayload, string expectedAtomicGroupId, string expectedAtomicGroupAId) { IODataResponseMessage responseMessage = new InMemoryMessage() { Stream = new MemoryStream(responsePayload) }; responseMessage.SetHeader("Content-Type", batchContentTypeApplicationJson); using (var messageReader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), this.userModel)) { var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: ODataBatchOperationResponseMessage operationMessage = batchReader.CreateOperationResponseMessage(); string responseId = operationMessage.ContentId; if (responseId.Equals("1") || responseId.Equals("2")) { // Verify the group id of the responses is correlated to the group id from the data modification requests. Assert.Equal(operationMessage.GroupId, expectedAtomicGroupId); Assert.True(operationMessage.StatusCode == 201 || operationMessage.StatusCode == 204); } else if (responseId.Equals("1A") || responseId.Equals("2A")) { // Verify the group id of the responses is correlated to the group id from the data modification requests. Assert.Equal(operationMessage.GroupId, expectedAtomicGroupAId); Assert.True(operationMessage.StatusCode == 201 || operationMessage.StatusCode == 204); } else if (responseId.Equals("3") || responseId.Equals("3A")) { // Verify the group id of the query response. Assert.Null(operationMessage.GroupId); } else { Assert.True(false, "Unexpected response id received: " + responseId); } break; default: break; } } } }
public void JsonPaddingEnabledWithUserSpecifiedContentType() { var settings = new ODataMessageWriterSettings {JsonPCallback = "functionName", DisableMessageStreamDisposal = true}; settings.SetServiceDocumentUri(new Uri("http://stuff")); IODataResponseMessage message = new InMemoryMessage {StatusCode = 200, Stream = new MemoryStream()}; message.SetHeader("Content-Type", "application/json"); var property = new ODataProperty {Name = "PropertyName", Value = "value"}; using (var writer = new ODataMessageWriter(message, settings)) { writer.WriteProperty(property); } var responseStream = message.GetStream(); responseStream.Position = 0; var responseString = new StreamReader(responseStream).ReadToEnd(); responseString.Should().Be("functionName({\"@odata.context\":\"http://stuff/$metadata#Edm.String\",\"value\":\"value\"})"); message.GetHeader("Content-Type").Should().StartWith("text/javascript"); }
private void ClientReadAsyncBatchResponse(byte[] responsePayload) { IODataResponseMessage responseMessage = new InMemoryMessage() { Stream = new MemoryStream(responsePayload) }; responseMessage.SetHeader("Content-Type", batchContentType); using (var messageReader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), this.userModel)) { 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.CreateOperationResponseMessage(); if (operationMessage.StatusCode == 200) { using (ODataMessageReader innerMessageReader = new ODataMessageReader(operationMessage, new ODataMessageReaderSettings(), this.userModel)) { var reader = innerMessageReader.CreateODataEntryReader(); while (reader.Read()) { if (reader.State == ODataReaderState.EntryEnd) { ODataEntry entry = reader.Item as ODataEntry; Assert.Equal("ALFKI", entry.Properties.Single(p => p.Name == "Id").Value); Assert.Equal("John", entry.Properties.Single(p => p.Name == "Name").Value); } } } } else { Assert.Equal(202, operationMessage.StatusCode); } break; } } } }
private static void ReadResponseEntryPayload(EdmModel userModel, string payload, EdmEntitySet entitySet, IEdmEntityType entityType, Action<ODataReader> action) { string contentType = "application/atom+xml;type=entry"; var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader("Content-Type", contentType); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true }; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, readerSettings, userModel)) { var reader = msgReader.CreateODataEntryReader(entitySet, entityType); while (reader.Read()) { action(reader); } } }
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); } } }
private ODataAsynchronousReader CreateAsyncReader() { IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream }; responseMessage.SetHeader("Content-Type", "application/http"); responseMessage.SetHeader("Content-Transfer-Encoding", "binary"); var messageReader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), userModel); return messageReader.CreateODataAsynchronousReader(); }
private void ReadFeedPayload(string payload, Action<ODataReader> action, bool isResponse = true, ODataVersion maxProtocolVersion = ODataVersion.V4) { if (isResponse) { IODataResponseMessage message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)), StatusCode = 200 }; message.SetHeader("Content-Type", "application/atom+xml;type=feed"); ODataMessageReaderSettings settings = new ODataMessageReaderSettings() { MaxProtocolVersion = maxProtocolVersion, EnableAtom = true }; using (var msgReader = new ODataMessageReader(message, settings)) { var reader = msgReader.CreateODataFeedReader(); while (reader.Read()) { action(reader); } } } else { IODataRequestMessage message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)), Method = "GET" }; message.SetHeader("Content-Type", "application/atom+xml;type=feed"); ODataMessageReaderSettings settings = new ODataMessageReaderSettings() { MaxProtocolVersion = maxProtocolVersion, EnableAtom = true }; using (var msgReader = new ODataMessageReader(message, settings)) { var reader = msgReader.CreateODataFeedReader(); while (reader.Read()) { action(reader); } } } }
private ODataProperty ReadPropertyOfEntry(string payload, string propertyName, ODataMessageReaderSettings settings, string contentType) { var message = new InMemoryMessage { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader("Content-Type", contentType); var reader = new ODataMessageReader((IODataResponseMessage)message, settings, this.model); var entryReader = reader.CreateODataEntryReader(this.entityType); entryReader.Read().Should().BeTrue(); entryReader.State.Should().Be(ODataReaderState.EntryStart); entryReader.Read().Should().BeTrue(); entryReader.State.Should().Be(ODataReaderState.EntryEnd); entryReader.Item.Should().BeAssignableTo<ODataEntry>(); entryReader.Item.As<ODataEntry>().Properties.Should().Contain(p => p.Name == propertyName); var property = entryReader.Item.As<ODataEntry>().Properties.Single(p => p.Name == propertyName); return property; }
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; }
private void ReadFeedPayload(string payload, Action<ODataReader> action) { var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader("Content-Type", "application/atom+xml;type=feed"); message.PreferenceAppliedHeader().AnnotationFilter = "*"; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, atomReaderSettings)) { var reader = msgReader.CreateODataFeedReader(); while (reader.Read()) { action(reader); } } }
public void ReadFeedWithActionAndFunctionTest() { string payload = "{\"" + "@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet\"," + "\"#Namespace.Action\":{" + "\"title\":\"ActionTitle\"," + "\"target\":\"http://example.org/odata.svc/DoAction\"" + "}," + "\"#Namespace.Function\":{" + "\"title\":\"FunctionTitle\"," + "\"target\":\"http://example.org/odata.svc/DoFunction\"" + "}," + "\"value\":[" + "{" + "\"ID\":101,\"Name\":\"Alice\"" + "}" + "]" + "}"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); List<ODataFeed> feedList = new List<ODataFeed>(); using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, ModelWithFunction)) { messageReader.DetectPayloadKind().Single().PayloadKind.Should().Be(ODataPayloadKind.Feed); var reader = messageReader.CreateODataFeedReader(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.FeedEnd: feedList.Add(reader.Item as ODataFeed); break; } } } ODataFeed feed = feedList[0]; feed.Actions.Count().Should().Be(1); feed.Functions.Count().Should().Be(1); }
public void ReadingContainedWithSubContextUrlShouldThrow() { string payload = "{\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet(ID,Name,ExpandedNavProp,ContainedCollectionNavProp,ContainedNavProp,ContainedCollectionNavProp(ID),ContainedNavProp(ID,Name))/$entity\"," + "\"ID\":101,\"Name\":\"Alice\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"ContainedCollectionNavProp\":[" + "{\"ID\":102,\"Name\":\"Bob\"}" + "]" + "}"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); List<ODataEntry> entryList = new List<ODataEntry>(); Action readContainedEntry = () => { using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, Model)) { var reader = messageReader.CreateODataEntryReader(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryEnd: entryList.Add(reader.Item as ODataEntry); break; } } } foreach (var oDataEntry in entryList) { oDataEntry.Id.Should().NotBeNull(); } }; readContainedEntry.ShouldThrow<ODataException>().WithMessage(ErrorStrings.ODataMetadataBuilder_MissingODataUri); }
// TODO: ATOM top level individual property testings // FlagsEnumAsComplexPropertyAsTopLevelValue_StrAsValue_StrAsTypeName // FlagsEnumAsCollectionItemAsTopLevelValue_StrAsValue_StrAsTypeName #endregion #region private methods public void ReadFromMessageReaderAndVerifyPayload(string payload, Action<ODataMessageReader> readerAction) { string contentType = "application/xml;"; var settings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true }; // with model { IODataResponseMessage message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader(ODataConstants.ContentTypeHeader, contentType); using (ODataMessageReader reader = new ODataMessageReader(message, settings, this.userModel)) { readerAction(reader); } } // without model should fail Action action = () => { IODataResponseMessage message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader(ODataConstants.ContentTypeHeader, contentType); message.SetHeader(ODataConstants.ContentTypeHeader, contentType); using (ODataMessageReader reader = new ODataMessageReader(message, settings)) { readerAction(reader); } }; action.ShouldThrow<Exception>(); }
public void CustomInstanceAnnotationFromFeedAndEntryInJsonLightShouldBeSkippedByTheReaderByDefault() { var stream = new MemoryStream(Encoding.UTF8.GetBytes(JsonLightFeedAndEntryPayloadWithCustomInstanceAnnotations)); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false }; IODataResponseMessage messageToRead = new InMemoryMessage { StatusCode = 200, Stream = stream }; messageToRead.SetHeader("Content-Type", "application/json;odata.streaming=true"); using (var messageReader = new ODataMessageReader(messageToRead, readerSettings, Model)) { var odataReader = messageReader.CreateODataFeedReader(EntitySet, EntityType); while (odataReader.Read()) { switch (odataReader.State) { case ODataReaderState.FeedStart: case ODataReaderState.FeedEnd: odataReader.Item.As<ODataFeed>().InstanceAnnotations.Should().BeEmpty(); break; case ODataReaderState.NavigationLinkStart: case ODataReaderState.NavigationLinkEnd: break; case ODataReaderState.EntryStart: case ODataReaderState.EntryEnd: odataReader.Item.As<ODataEntry>().InstanceAnnotations.Should().BeEmpty(); break; } } } }
/// <summary> /// Reads an ODataError from the stream and returns it for verification. /// </summary> private ODataError ReadError() { ODataError readError; var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false }; IODataResponseMessage messageToRead = new InMemoryMessage { StatusCode = 400, Stream = this.stream }; messageToRead.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); using (var reader = new ODataMessageReader(messageToRead, readerSettings, this.model)) { readError = reader.ReadError(); } return readError; }
private static ODataMessageWriter CreateODataMessageWriter(IEdmModel model, string contentType) { var settings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, Version = ODataVersion.V4, EnableAtom = true }; settings.SetServiceDocumentUri(new Uri("http://example.com")); var message = new InMemoryMessage(); message.Stream = new MemoryStream(); message.SetHeader("Accept", contentType); message.SetHeader("Content-Type", contentType); message.SetHeader("OData-Version", "4.0"); if (model == null) { return new ODataMessageWriter((IODataRequestMessage)message, settings); } else { return new ODataMessageWriter((IODataRequestMessage)message, settings, model); } }
public void ReadingEntryExpandWithMixedCollectionAndNonCollectionContainedElementAtSameLevel() { string payload = "{\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet(ID,Name,ExpandedNavProp,ContainedCollectionNavProp,ContainedNavProp,ContainedCollectionNavProp(ID),ContainedNavProp(ID,Name))/$entity\"," + "\"ID\":101,\"Name\":\"Alice\"," + "\"ExpandedNavProp\":{\"ID\":102,\"Name\":\"Bob\"}," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedCollectionNavProp(ID)\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"ContainedCollectionNavProp\":[" + "{\"ID\":102,\"Name\":\"Bob\"}" + "]," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedNavProp(ID,Name)/$entity\"," + "\"ContainedNavProp\":{\"ID\":103,\"Name\":\"Charlie\"}" + "}"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); List<ODataEntry> entryList = new List<ODataEntry>(); using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, Model)) { var reader = messageReader.CreateODataEntryReader(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryEnd: entryList.Add(reader.Item as ODataEntry); break; } } } ODataEntry bobEntry = entryList[0]; ODataEntry containedBobEntry = entryList[1]; ODataEntry containedCharileEntry = entryList[2]; ODataEntry topLevelAliceEntry = entryList[3]; bobEntry.Id.Should().Be("http://example.org/odata.svc/EntitySet(102)"); containedBobEntry.Id.Should().Be("http://example.org/odata.svc/EntitySet(101)/ContainedCollectionNavProp(102)"); containedCharileEntry.Id.Should().Be("http://example.org/odata.svc/EntitySet(101)/ContainedNavProp"); topLevelAliceEntry.Id.Should().Be("http://example.org/odata.svc/EntitySet(101)"); }
private static ODataMessageReader CreateODataMessageReader(string payload, string contentType, bool isResponse, bool shouldReadAndValidateCustomInstanceAnnotations, bool odataSimplified = false) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true, ODataSimplified = odataSimplified }; ODataMessageReader messageReader; if (isResponse) { IODataResponseMessage responseMessage = new InMemoryMessage { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", contentType); if (shouldReadAndValidateCustomInstanceAnnotations) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; } messageReader = new ODataMessageReader(responseMessage, readerSettings, Model); } else { IODataRequestMessage requestMessage = new InMemoryMessage { Method = "GET", Stream = stream }; requestMessage.SetHeader("Content-Type", contentType); readerSettings.ShouldIncludeAnnotation = shouldReadAndValidateCustomInstanceAnnotations ? ODataUtils.CreateAnnotationFilter("*") : null; messageReader = new ODataMessageReader(requestMessage, readerSettings, Model); } return messageReader; }
public void ReadingNestedInlinecountTest() { string payload = "{" + "\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet\"," + "\"value\":[" + "{" + "\"ID\":101,\"Name\":\"Alice\"," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedCollectionNavProp\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"[email protected]\":1900," + "\"ContainedCollectionNavProp\":[]" + "}" + "]" + "}"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); List<ODataFeed> feedList = new List<ODataFeed>(); using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, Model)) { var reader = messageReader.CreateODataFeedReader(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.FeedEnd: feedList.Add(reader.Item as ODataFeed); break; } } } ODataFeed innerFeed = feedList[0]; innerFeed.Count.Should().Be(1900); ODataFeed topFeed = feedList[1]; topFeed.Count.Should().Be(null); }
private string GetWriterOutputForContentTypeAndKnobValue(ODataEntry entry, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType) { MemoryStream outputStream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream }; message.SetHeader("Content-Type", "application/json;odata.metadata=full"); ODataMessageWriterSettings settings = new ODataMessageWriterSettings() { AutoComputePayloadMetadataInJson = true, }; settings.SetServiceDocumentUri(new Uri("http://example.com")); string output; using (var messageWriter = new ODataMessageWriter(message, settings, model)) { ODataWriter writer = messageWriter.CreateODataEntryWriter(entitySet, entityType); writer.WriteStart(entry); writer.WriteEnd(); outputStream.Seek(0, SeekOrigin.Begin); output = new StreamReader(outputStream).ReadToEnd(); } return output; }
private string SerializeEntryInFullMetadataJson( bool? useKeyAsSegment, IEdmModel edmModel, IEdmEntityType entityType = null, IEdmEntitySet entitySet = null) { var settings = new ODataMessageWriterSettings { AutoComputePayloadMetadataInJson = true, UseKeyAsSegment = useKeyAsSegment, }; settings.SetServiceDocumentUri(new Uri("http://example.com/")); var outputStream = new MemoryStream(); var responseMessage = new InMemoryMessage {Stream = outputStream}; responseMessage.SetHeader("Content-Type", "application/json;odata.metadata=full"); string output; using(var messageWriter = new ODataMessageWriter((IODataResponseMessage)responseMessage, settings, edmModel)) { var entryWriter = messageWriter.CreateODataEntryWriter(entitySet, entityType); ODataProperty keyProperty = new ODataProperty() {Name = "Key", Value = "KeyValue"}; var entry = new ODataEntry {Properties = new[] {keyProperty}, TypeName = "Namespace.Person"}; if (edmModel == null) { keyProperty.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }); entry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceEntityTypeName = "Namespace.Person", NavigationSourceName = "People", ExpectedTypeName = "Namespace.Person" }); } entryWriter.WriteStart(entry); entryWriter.WriteEnd(); entryWriter.Flush(); outputStream.Seek(0, SeekOrigin.Begin); output = new StreamReader(outputStream).ReadToEnd(); } return output; }
public void ReadingInMinialMetadataModeWithContainedEntitySetOfAnotherTypeShouldBeAbleToGenerateId() { const string payload = "{" + "\"@odata.context\":\"http://example.com/$metadata#EntitySet(1)/AnotherContainedNavProp\"," + "\"value\":[" + "{" + "\"ID\" : 123," + "\"Name\" : \"Bob\"" + "}" + "] }"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); ODataEntry topLevelEntry = null; List<ODataEntry> entryList = new List<ODataEntry>(); using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, Model)) { var navProp = EntityType.FindProperty("AnotherContainedNavProp") as IEdmNavigationProperty; var containedEntitySet = EntitySet.FindNavigationTarget(navProp) as IEdmEntitySetBase; var reader = messageReader.CreateODataFeedReader(containedEntitySet, AnotherEntityType); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryEnd: topLevelEntry = (ODataEntry)reader.Item; entryList.Add(topLevelEntry); break; } } } Uri containedId = new Uri("http://example.com/EntitySet(1)/AnotherContainedNavProp(123)"); ODataEntry containedEntry = entryList[0]; containedEntry.Id.Should().Be(containedId); }
private IEdmModel ReadMetadataDocument(Dictionary<string, string> map, string mainUrl) { Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(map[mainUrl])); IODataResponseMessage responseMessage = new InMemoryMessage() { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", "application/xml"); ODataMessageReader reader = new ODataMessageReader(responseMessage); return reader.ReadMetadataDocument((uri) => { string uriStr = uri.ToString(); if (map.ContainsKey(uriStr)) { return new XmlTextReader(new StringReader(map[uriStr])); } return null; }); }
public void ReadingInMinialMetadataModeWithContainedElementShouldBeAbleToGenerateId() { const string payload = "{" + "\"@odata.context\":\"http://example.com/$metadata#EntitySet(ContainedNavProp2,ExpandedNavLink,ExpandedNavLink(ContainedNavProp2))\"," + "\"value\":[" + "{" + "\"[email protected]\":\"http://example.com/$metadata#EntitySet(123)/ContainedNonCollectionNavProp/$entity\"," + "\"ContainedNonCollectionNavProp\":" + "{" + "\"ID\": 234," + "\"Name\":\"Foo\"" + "}," + "\"ID\" : 123," + "\"Name\" : \"Bob\"" + "} ] }"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=mini"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); ODataEntry topLevelEntry = null; List<ODataEntry> entryList = new List<ODataEntry>(); using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, Model)) { var reader = messageReader.CreateODataFeedReader(EntitySet, EntityType); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryEnd: topLevelEntry = (ODataEntry)reader.Item; entryList.Add(topLevelEntry); break; } } } Uri containedId = new Uri("http://example.com/EntitySet(123)/ContainedNonCollectionNavProp"); ODataEntry containedEntry = entryList[0]; containedEntry.Id.Should().Be(containedId); }
private void ReadEntryPayload(string payload, Action<ODataReader> action) { var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader("Content-Type", "application/atom+xml;type=entry"); ODataMessageReaderSettings settings = new ODataMessageReaderSettings { EnableAtom = true }; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, settings)) { var reader = msgReader.CreateODataEntryReader(); while (reader.Read()) { action(reader); } } }
private void CreateMessageReader(string payloadBody, bool forEntry, bool isResponse, bool odataSimplified) { string payloadPrefix = @"{ ""@odata.context"":""http://example.com/$metadata#EntitySet" + (forEntry ? "/$entity" : string.Empty) + "\","; const string payloadSuffix = "}"; string payload = payloadPrefix + payloadBody + payloadSuffix; var message = new InMemoryMessage(); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal;odata.streaming=true"); var messageSettings = new ODataMessageReaderSettings { ODataSimplified = odataSimplified }; if (isResponse) { this.messageReader = new ODataMessageReader((IODataResponseMessage)message, messageSettings, this.model); } else { this.messageReader = new ODataMessageReader((IODataRequestMessage)message, messageSettings, this.model); } }
public void ShouldBeAbleToReadCustomInstanceAnnotationFromFeedAndEntry(string payload, string contentType) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true }; IODataResponseMessage messageToRead = new InMemoryMessage { StatusCode = 200, Stream = stream }; messageToRead.SetHeader("Content-Type", contentType); // Enable reading custom instance annotations. messageToRead.PreferenceAppliedHeader().AnnotationFilter = "Custom.*"; Stack<ODataItem> odataItems = new Stack<ODataItem>(4); using (var messageReader = new ODataMessageReader(messageToRead, readerSettings, Model)) { var odataReader = messageReader.CreateODataFeedReader(EntitySet, EntityType); ICollection<ODataInstanceAnnotation> instanceAnnotations = null; while (odataReader.Read()) { switch (odataReader.State) { case ODataReaderState.FeedStart: odataItems.Push(odataReader.Item); instanceAnnotations = odataItems.Peek().As<ODataFeed>().InstanceAnnotations; // TODO: We only support instance annotation at the top level feed at the moment. Will remove the if statement when support on inline feed is added. if (odataItems.Count == 1) { // Note that in streaming mode, the collection should be populated with instance annotations read so far before the beginning of the first entry. // We are currently in non-streaming mode. The reader will buffer the payload and read ahead till the // end of the feed to read all instance annotations. instanceAnnotations.Should().HaveCount(1); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedStartAnnotation").Value); } else { instanceAnnotations.Should().BeEmpty(); } break; case ODataReaderState.FeedEnd: instanceAnnotations = odataItems.Peek().As<ODataFeed>().InstanceAnnotations; // TODO: We only support instance annotation at the top level feed at the moment. Will remove the if statement when support on inline feed is added. if (odataItems.Count == 1) { instanceAnnotations.Should().HaveCount(2); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedEndAnnotation").Value); } else { instanceAnnotations.Should().BeEmpty(); } odataItems.Pop(); break; case ODataReaderState.NavigationLinkStart: ODataNavigationLink navigationLink = (ODataNavigationLink)odataReader.Item; if (navigationLink.Name == "ResourceSetNavigationProperty") { // The collection should be populated with instance annotations read so far before the "ResourceSetNavigationProperty". instanceAnnotations = odataItems.Peek().As<ODataEntry>().InstanceAnnotations; instanceAnnotations.Should().HaveCount(2); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryMiddleAnnotation").Value); } break; case ODataReaderState.NavigationLinkEnd: break; case ODataReaderState.EntryStart: odataItems.Push(odataReader.Item); // The collection should be populated with instance annotations read so far before the first navigation/association link or before the end of the entry. instanceAnnotations = odataItems.Peek().As<ODataEntry>().InstanceAnnotations; instanceAnnotations.Should().HaveCount(1); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryStartAnnotation").Value); break; case ODataReaderState.EntryEnd: instanceAnnotations = odataItems.Peek().As<ODataEntry>().InstanceAnnotations; instanceAnnotations.Should().HaveCount(3); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryMiddleAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryEndAnnotation").Value); odataItems.Pop(); break; } } instanceAnnotations.Should().HaveCount(2); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedEndAnnotation").Value); } }
private ParameterReaderResult RunParameterReaderTest(string payload) { var message = new InMemoryMessage(); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); message.SetHeader("Content-Type", "application/json"); var parameterReaderResult = new ParameterReaderResult(); using (var messageReader = new ODataMessageReader((IODataRequestMessage)message, null, this.model)) { var parameterReader = messageReader.CreateODataParameterReader(this.action); while (parameterReader.Read()) { switch (parameterReader.State) { case ODataParameterReaderState.Value: { parameterReaderResult.Values.Add(new KeyValuePair<string, object>(parameterReader.Name, parameterReader.Value)); break; } case ODataParameterReaderState.Collection: { var collection = new ParameterReaderCollection(); parameterReaderResult.Collections.Add(new KeyValuePair<string, ParameterReaderCollection>(parameterReader.Name, collection)); var collectionReader = parameterReader.CreateCollectionReader(); while (collectionReader.Read()) { switch (collectionReader.State) { case ODataCollectionReaderState.Value: { collection.Items.Add(collectionReader.Item); break; } } } break; } case ODataParameterReaderState.Entry: { var entryReader = parameterReader.CreateEntryReader(); var entryList = new List<ODataEntry>(); parameterReaderResult.Entries.Add(new KeyValuePair<string, IList<ODataEntry>>(parameterReader.Name, entryList)); while (entryReader.Read()) { switch (entryReader.State) { case ODataReaderState.EntryEnd: entryList.Add((ODataEntry)entryReader.Item); break; } } break; } case ODataParameterReaderState.Feed: { var entryReader = parameterReader.CreateFeedReader(); var entryList = new List<ODataEntry>(); parameterReaderResult.Entries.Add(new KeyValuePair<string, IList<ODataEntry>>(parameterReader.Name, entryList)); var feedList = new List<ODataFeed>(); parameterReaderResult.Feeds.Add(new KeyValuePair<string, IList<ODataFeed>>(parameterReader.Name, feedList)); while (entryReader.Read()) { switch (entryReader.State) { case ODataReaderState.EntryEnd: entryList.Add((ODataEntry)entryReader.Item); break; case ODataReaderState.FeedEnd: feedList.Add((ODataFeed)entryReader.Item); break; } } break; } } } } return parameterReaderResult; }