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 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 JsonPaddingEnabledWithRawValueSpecified() { var settings = new ODataMessageWriterSettings {JsonPCallback = "functionName", DisableMessageStreamDisposal = true}; settings.SetContentType(ODataFormat.RawValue); IODataResponseMessage message = new InMemoryMessage {StatusCode = 200, Stream = new MemoryStream()}; using (var writer = new ODataMessageWriter(message, settings)) { writer.WriteValue(123); } var responseStream = message.GetStream(); responseStream.Position = 0; var responseString = new StreamReader(responseStream).ReadToEnd(); responseString.Should().Be("functionName(123)"); message.GetHeader("Content-Type").Should().StartWith("text/javascript"); }
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 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; })); }
private ODataItemBase ReadPayload(string payload, IEdmModel edmModel, Func <ODataMessageReader, ODataReader> createReader) { var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings() { BaseUri = new Uri("http://localhost/$metadata"), EnableMessageStreamDisposal = true, Version = ODataVersion.V4, }; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, readerSettings, edmModel)) { ODataReader reader = createReader(msgReader); return(reader.ReadResourceOrResourceSet()); } }
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); } } }
public void BatchJsonLightAtomicGroupCannotCreateGroupIdWithNullValue() { MemoryStream stream = new MemoryStream(); IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream }; requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson); ODataMessageWriterSettings settings = new ODataMessageWriterSettings(); settings.BaseUri = new Uri(serviceDocumentUri); using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, settings)) { ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); ArgumentNullException ane = Assert.Throws <ArgumentNullException>(() => batchWriter.WriteStartChangeset(null)); Assert.True(ane.Message.Contains("changesetId")); } }
protected void WriteAnnotationsAndValidatePayload(Action <ODataWriter> action, ODataFormat format, string expectedPayload, bool request, bool createFeedWriter) { var writerSettings = new ODataMessageWriterSettings { EnableMessageStreamDisposal = false }; writerSettings.SetContentType(format); writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/")); MemoryStream stream = new MemoryStream(); if (request) { IODataRequestMessage requestMessageToWrite = new InMemoryMessage { Method = "GET", Stream = stream }; using (var messageWriter = new ODataMessageWriter(requestMessageToWrite, writerSettings, Model)) { ODataWriter odataWriter = createFeedWriter ? messageWriter.CreateODataResourceSetWriter(EntitySet, EntityType) : messageWriter.CreateODataResourceWriter(EntitySet, EntityType); action(odataWriter); } } else { IODataResponseMessage responseMessageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; using (var messageWriter = new ODataMessageWriter(responseMessageToWrite, writerSettings, Model)) { ODataWriter odataWriter = createFeedWriter ? messageWriter.CreateODataResourceSetWriter(EntitySet, EntityType) : messageWriter.CreateODataResourceWriter(EntitySet, EntityType); action(odataWriter); } } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); Assert.Equal(expectedPayload, payload); }
private void ServiceProcessBatchRequest(ODataJsonBatchPayloadTestCase testCase, ODataVersion version) { string requestPayload = testCase.RequestPayload; ODataJsonBatchPayloadTestCase.ValidateContentType requestMessageContentTypeVerifier = testCase.ContentTypeVerifier; IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(Encoding.ASCII.GetBytes(requestPayload)) }; requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson); using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, new ODataMessageReaderSettings() { Version = version, BaseUri = new Uri("http://odata.org") }, this.edmModel)) { ODataBatchReader batchReader = messageReader.CreateODataBatchReader(); int operationIdx = 0; while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: ODataBatchOperationRequestMessage operationMessage = batchReader.CreateOperationRequestMessage(); // Verify operation message content type processing. requestMessageContentTypeVerifier.Invoke(operationMessage, operationIdx); operationIdx++; break; } } } }
private static string GetWriterOutput(ODataResource entry, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType, IServiceProvider container) { var outputStream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage { Stream = outputStream, Container = container }; message.SetHeader("Content-Type", "application/json"); var settings = new ODataMessageWriterSettings(); settings.SetServiceDocumentUri(new Uri("http://test")); using (var messageWriter = new ODataMessageWriter(message, settings, model)) { var writer = messageWriter.CreateODataResourceWriter(entitySet, entityType); writer.WriteStart(entry); writer.WriteEnd(); outputStream.Seek(0, SeekOrigin.Begin); return(new StreamReader(outputStream).ReadToEnd()); } }
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)); } }
private static ODataMessageReader CreateODataMessageReader(string payload, string contentType, bool isResponse, bool shouldReadAndValidateCustomInstanceAnnotations, bool enableReadingODataAnnotationWithoutPrefix = false) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); var readerSettings = new ODataMessageReaderSettings { EnableMessageStreamDisposal = false }; var container = ContainerBuilderHelper.BuildContainer(null); container.GetRequiredService <ODataSimplifiedOptions>().EnableReadingODataAnnotationWithoutPrefix = enableReadingODataAnnotationWithoutPrefix; ODataMessageReader messageReader; if (isResponse) { IODataResponseMessage responseMessage = new InMemoryMessage { StatusCode = 200, Stream = stream, Container = container }; 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, Container = container }; requestMessage.SetHeader("Content-Type", contentType); readerSettings.ShouldIncludeAnnotation = shouldReadAndValidateCustomInstanceAnnotations ? ODataUtils.CreateAnnotationFilter("*") : null; messageReader = new ODataMessageReader(requestMessage, readerSettings, Model); } return(messageReader); }
private string WriterEntry(IEdmModel userModel, ODataResource entry, EdmEntitySet entitySet, IEdmEntityType entityType, bool fullMetadata = false, Action <ODataWriter> writeAction = null) { var message = new InMemoryMessage() { Stream = new MemoryStream() }; var writerSettings = new ODataMessageWriterSettings { EnableMessageStreamDisposal = false }; writerSettings.SetContentType(ODataFormat.Json); writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com")); writerSettings.SetContentType(fullMetadata ? "application/json;odata.metadata=full;odata.streaming=false" : "application/json;odata.metadata=minimal;odata.streaming=false", "utf-8"); using (var msgReader = new ODataMessageWriter((IODataResponseMessage)message, writerSettings, userModel)) { var writer = msgReader.CreateODataResourceWriter(entitySet, entityType); if (writeAction != null) { writeAction(writer); } else { writer.WriteStart(entry); writer.WriteEnd(); } } message.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(message.Stream)) { return(reader.ReadToEnd()); } }
private void ClientReadBatchResponse(byte[] responsePayload) { 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(); if (operationMessage.StatusCode == 200) { using (ODataMessageReader innerMessageReader = new ODataMessageReader( operationMessage, new ODataMessageReaderSettings(), this.userModel)) { ODataReader reader = innerMessageReader.CreateODataResourceReader(); while (reader.Read()) { } } } break; default: break; } } } }
protected void WriteAnnotationsAndValidatePayload(Action<ODataWriter> action, ODataFormat format, string expectedPayload, bool request, bool createFeedWriter) { var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, EnableAtom = true }; writerSettings.SetContentType(format); writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/")); MemoryStream stream = new MemoryStream(); if (request) { IODataRequestMessage requestMessageToWrite = new InMemoryMessage { Method = "GET", Stream = stream }; using (var messageWriter = new ODataMessageWriter(requestMessageToWrite, writerSettings, Model)) { ODataWriter odataWriter = createFeedWriter ? messageWriter.CreateODataFeedWriter(EntitySet, EntityType) : messageWriter.CreateODataEntryWriter(EntitySet, EntityType); action(odataWriter); } } else { IODataResponseMessage responseMessageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; using (var messageWriter = new ODataMessageWriter(responseMessageToWrite, writerSettings, Model)) { ODataWriter odataWriter = createFeedWriter ? messageWriter.CreateODataFeedWriter(EntitySet, EntityType) : messageWriter.CreateODataEntryWriter(EntitySet, EntityType); action(odataWriter); } } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); if (format == ODataFormat.Atom) { // The <updated> element is computed dynamically, so we remove it from the both the baseline and the actual payload. payload = Regex.Replace(payload, "<updated>[^<]*</updated>", ""); expectedPayload = Regex.Replace(expectedPayload, "<updated>[^<]*</updated>", ""); } Assert.Equal(expectedPayload, payload); }
public void CustomInstanceAnnotationFromFeedAndEntryInJsonLightShouldBeSkippedByTheReaderByDefault() { var stream = new MemoryStream(Encoding.UTF8.GetBytes(JsonLightFeedAndEntryPayloadWithCustomInstanceAnnotations)); var readerSettings = new ODataMessageReaderSettings { EnableMessageStreamDisposal = true }; 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.CreateODataResourceSetReader(EntitySet, EntityType); while (odataReader.Read()) { switch (odataReader.State) { case ODataReaderState.ResourceSetStart: case ODataReaderState.ResourceSetEnd: var resourceSet = Assert.IsType <ODataResourceSet>(odataReader.Item); Assert.Empty(resourceSet.InstanceAnnotations); break; case ODataReaderState.NestedResourceInfoStart: case ODataReaderState.NestedResourceInfoEnd: break; case ODataReaderState.ResourceStart: case ODataReaderState.ResourceEnd: Assert.Empty((odataReader.Item as ODataResource).InstanceAnnotations); break; } } } }
private string WriteODataEntry(ODataEntry entryToWrite) { var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true }; writerSettings.SetContentType(ODataFormat.Json); writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/")); MemoryStream stream = new MemoryStream(); IODataRequestMessage requestMessageToWrite = new InMemoryMessage { Method = "GET", Stream = stream }; using (var messageWriter = new ODataMessageWriter(requestMessageToWrite, writerSettings, this.model)) { ODataWriter odataWriter = messageWriter.CreateODataEntryWriter(this.entitySet, this.entityType); odataWriter.WriteStart(entryToWrite); odataWriter.WriteEnd(); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); return(payload); }
public void JsonPaddingEnabledWithRawValueSpecified() { var settings = new ODataMessageWriterSettings { JsonPCallback = "functionName", EnableMessageStreamDisposal = false }; settings.SetContentType(ODataFormat.RawValue); IODataResponseMessage message = new InMemoryMessage { StatusCode = 200, Stream = new MemoryStream() }; using (var writer = new ODataMessageWriter(message, settings)) { writer.WriteValue(123); } var responseStream = message.GetStream(); responseStream.Position = 0; var responseString = new StreamReader(responseStream).ReadToEnd(); responseString.Should().Be("functionName(123)"); message.GetHeader("Content-Type").Should().StartWith("text/javascript"); }
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; } } } }
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); } }
// 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>(); }
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 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 WriterShouldNotIncludeTypeNameForCollectionOfDerivedType() { // JSON Light: writer doesn't include type name for collection of derived type // If I have a collection property declared in metadata as Collection(Edm.Geography), // and at serialization type, it's clearly a Collection(Edm.GeographyPoint), // we won't write the type name for that property by default (i.e., minimal metadata mode). var model = new EdmModel(); var entityType = new EdmEntityType("Var1", "Type"); entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); entityType.AddProperty(new EdmStructuralProperty(entityType, "Geographies", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false))))); model.AddElement(entityType); var writerSettings = new ODataMessageWriterSettings(); writerSettings.SetContentType(ODataFormat.Json); writerSettings.EnableMessageStreamDisposal = false; var message = new InMemoryMessage { Stream = new MemoryStream() }; using (ODataMessageWriter odataMessageWriter = new ODataMessageWriter((IODataRequestMessage)message, writerSettings, model)) { ODataWriter odataWriter = odataMessageWriter.CreateODataResourceWriter(); odataWriter.WriteStart( new ODataResource { TypeName = "Var1.Type", Properties = new[] { new ODataProperty() { Name = "Id", Value = 1 }, new ODataProperty() { Name = "Geographies", Value = new ODataCollectionValue { Items = new[] { GeographyPoint.Create(0, 0), GeographyPoint.Create(1, 1), GeographyPoint.Create(2, 2) } } }, } }); odataWriter.WriteEnd(); odataWriter.Flush(); } message.Stream.Position = 0; var output = new StreamReader(message.Stream).ReadToEnd(); Assert.IsFalse(output.Contains("Collection(Edm.GeographyPoint)"), @"output.Contains(""Collection(Edm.GeographyPoint)"" == false"); }
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()); } }
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; }
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); }
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 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.CreateODataEntryWriter(peopleSet); var entry = new ODataEntry { 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(); payload.Should().Be("{\"@odata.context\":\"http://host/service/$metadata#People/$entity\",\"ID\":\"18446744073709551615\",\"Name\":\"Foo\",\"FavoriteNumber\":250.0,\"Age\":123,\"Guid\":-9223372036854775808,\"Weight\":123.45,\"Money\":79228162514264337593543950335}"); stream = new MemoryStream(Encoding.Default.GetBytes(payload)); message = new InMemoryMessage { Stream = stream }; message.StatusCode = 200; var readerSettings = new ODataMessageReaderSettings(); var messageReader = new ODataMessageReader(message, readerSettings, model); var entryReader = messageReader.CreateODataEntryReader(peopleSet, personType); Assert.True(entryReader.Read()); var entryReaded = entryReader.Item as ODataEntry; 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); } }
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; }
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); } }
/// <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; }
/// <summary> /// Writes an ODataError with the given custom instance annotation to the test stream. /// </summary> private void WriteError(params KeyValuePair<string, ODataValue>[] annotations) { var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true }; writerSettings.SetContentType(ODataFormat.Json); writerSettings.SetServiceDocumentUri(new Uri("http://example.com/")); IODataResponseMessage messageToWrite = new InMemoryMessage { StatusCode = 400, Stream = this.stream }; var error = new ODataError(); var instanceAnnotations = new Collection<ODataInstanceAnnotation>(); error.SetInstanceAnnotations(instanceAnnotations); foreach (var pair in annotations) { ODataInstanceAnnotation annotation = new ODataInstanceAnnotation(pair.Key, pair.Value); instanceAnnotations.Add(annotation); } using (var writer = new ODataMessageWriter(messageToWrite, writerSettings, this.model)) { writer.WriteError(error, false); } }
public void ShouldBeAbleToWriteFeedAndEntryResponseInJsonLightWithoutModel() { const string expectedPayload = "{" + "\"@odata.context\":\"http://www.example.com/$metadata#Customers/NS.VIPCustomer\"," + "\"value\":[" + "{" + "\"Name\":\"Bob\"," + "\"[email protected]\":\"MostRecentOrder\"," + "\"MostRecentOrder\":{\"OrderId\":101}" + "}" + "]" + "}"; var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true }; writerSettings.SetContentType(ODataFormat.Json); writerSettings.ODataUri = new ODataUri() { ServiceRoot = new Uri("http://www.example.com") }; MemoryStream stream = new MemoryStream(); IODataResponseMessage responseMessage = new InMemoryMessage { StatusCode = 200, Stream = stream }; // Write payload using (var messageWriter = new ODataMessageWriter(responseMessage, writerSettings)) { var odataWriter = messageWriter.CreateODataFeedWriter(); // Create customers feed with serializtion info to write odata.metadata. var customersFeed = new ODataFeed(); customersFeed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Customers", NavigationSourceEntityTypeName = "NS.Customer", ExpectedTypeName = "NS.VIPCustomer" }); // Write customers feed. odataWriter.WriteStart(customersFeed); // Write VIP customer { // Create VIP customer, don't need to pass in serialization info since the writer knows the context from the feed scope. var vipCustomer = new ODataEntry { TypeName = "NS.VIPCustomer" }; var customerKey = new ODataProperty { Name = "Name", Value = "Bob" }; // Provide serialization info at the property level to compute the edit link. customerKey.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }); vipCustomer.Properties = new[] { customerKey }; // Write customer entry. odataWriter.WriteStart(vipCustomer); // Write expanded most recent order { // No API to set serialization info on ODataNavigationLink since what we are adding on ODataFeed and ODataEntry should be sufficient for the 5.5 release. var navigationLink = new ODataNavigationLink { Name = "MostRecentOrder", IsCollection = false, Url = new Uri("MostRecentOrder", UriKind.Relative) }; odataWriter.WriteStart(navigationLink); // Write the most recent customer. { var mostRecentOrder = new ODataEntry { TypeName = "NS.Order" }; // Add serialization info so we can computer links. mostRecentOrder.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Orders", NavigationSourceEntityTypeName = "NS.Order", ExpectedTypeName = "NS.Order" }); var orderKey = new ODataProperty { Name = "OrderId", Value = 101 }; // Provide serialization info at the property level to compute the edit link. orderKey.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }); mostRecentOrder.Properties = new[] { orderKey }; // Write order entry. odataWriter.WriteStart(mostRecentOrder); odataWriter.WriteEnd(); } // End navigationLink. odataWriter.WriteEnd(); } // End customer entry. odataWriter.WriteEnd(); } // End customers feed. odataWriter.WriteEnd(); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); payload.Should().Be(expectedPayload); }
private void WriteDeltaFeedAnnotationsAndValidatePayload(Action<ODataDeltaWriter> action, IEdmEntitySet entitySet, string expectedPayload) { var writerSettings = new ODataMessageWriterSettings {DisableMessageStreamDisposal = true}; writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/")); MemoryStream stream = new MemoryStream(); IODataResponseMessage responseMessageToWrite = new InMemoryMessage {StatusCode = 200, Stream = stream}; responseMessageToWrite.PreferenceAppliedHeader().AnnotationFilter = "*"; using (var messageWriter = new ODataMessageWriter(responseMessageToWrite, writerSettings, Model)) { ODataDeltaWriter odataDeltaWriter = messageWriter.CreateODataDeltaWriter(entitySet, EntityType); action(odataDeltaWriter); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); Assert.Equal(expectedPayload, payload); }
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 string WriteAtomEntry(ODataEntry entry) { MemoryStream stream = new MemoryStream(); InMemoryMessage message = new InMemoryMessage { Stream = stream }; var settings = new ODataMessageWriterSettings { Version = ODataVersion.V4, AutoComputePayloadMetadataInJson = true, EnableAtom = true}; settings.SetServiceDocumentUri(new Uri("http://temp.org/")); settings.SetContentType(ODataFormat.Atom); ODataMessageWriter messageWriter = new ODataMessageWriter((IODataResponseMessage)message, settings, Model); var entryWriter = messageWriter.CreateODataEntryWriter(EntitySet, EntityType); entryWriter.WriteStart(entry); entryWriter.WriteEnd(); entryWriter.Flush(); var actual = Encoding.UTF8.GetString(stream.ToArray()); return actual; }
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); }
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 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; }
private static void WriteCustomInstanceAnnotationToFeedAndEntry(string expectedPayload, ODataFormat format) { var writerSettings = new ODataMessageWriterSettings { EnableMessageStreamDisposal = false }; writerSettings.SetContentType(format); writerSettings.ODataUri = new ODataUri() { ServiceRoot = new Uri("http://www.example.com/") }; MemoryStream stream = new MemoryStream(); IODataResponseMessage messageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; messageToWrite.PreferenceAppliedHeader().AnnotationFilter = "Custom.*"; // Write payload using (var messageWriter = new ODataMessageWriter(messageToWrite, writerSettings, Model)) { var odataWriter = messageWriter.CreateODataResourceSetWriter(EntitySet, EntityType); // Add instance annotations to the feed. var feedToWrite = new ODataResourceSet { Id = new Uri("urn:feedId") }; feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.Int32Annotation", PrimitiveValue1)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.GuidAnnotation", PrimitiveValue2)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.Int32Annotation", PrimitiveValue1)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.GuidAnnotation", PrimitiveValue2)); // Writes instance annotations at the beginning of the feed odataWriter.WriteStart(feedToWrite); // Add instance annotations to the entry. var entryToWrite = new ODataResource { Properties = new[] { new ODataProperty { Name = "ID", Value = 1 } } }; entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.ComplexAnnotation", ResourceValue1)); entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.ComplexAnnotation", ResourceValue2)); // Writes instance annotations at the beginning of the entry odataWriter.WriteStart(entryToWrite); // Add more instance annotations to the entry. entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.PrimitiveCollectionAnnotation", PrimitiveCollectionValue)); entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.PrimitiveCollectionAnnotation", PrimitiveCollectionValue)); // The writer remembers which instance annotations in the collection has been written // and only write out the unwritten ones since WriteStart() to the end of the entry. odataWriter.WriteEnd(); // Add more instance annotations to the feed. feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.ComplexCollectionAnnotation", ComplexCollectionValue)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.ComplexCollectionAnnotation", ComplexCollectionValue)); // The writer remembers which instance annotations in the collection has been written // and only write out the unwritten ones since WriteStart() to the end of the feed. odataWriter.WriteEnd(); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); Assert.Equal(payload, expectedPayload); }
// TODO: ATOM top level individual property testings // FlagsEnumAsComplexPropertyAsTopLevelValue_StrAsValue_StrAsTypeName // FlagsEnumAsCollectionItemAsTopLevelValue_StrAsValue_StrAsTypeName #endregion #region private methods public void WriteToMessageWriterAndVerifyPayload(string contentType, Action<ODataMessageWriter> writerAction, string expectedPayload) { ODataMessageWriterSettings settings = new ODataMessageWriterSettings() { Version = ODataVersion.V4, AutoComputePayloadMetadataInJson = true, DisableMessageStreamDisposal = true, EnableAtom = true}; settings.SetContentType(contentType, "utf-8"); settings.SetServiceDocumentUri(ServiceDocumentUri); // with model { MemoryStream stream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage() { Stream = stream }; using (ODataMessageWriter writer = new ODataMessageWriter(message, settings, this.userModel)) { writerAction(writer); } stream.Seek(0, SeekOrigin.Begin); string payload = (new StreamReader(stream)).ReadToEnd(); payload.Should().Be(expectedPayload); } // without model { MemoryStream stream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage() { Stream = stream }; using (ODataMessageWriter writer = new ODataMessageWriter(message, settings)) { writerAction(writer); } stream.Seek(0, SeekOrigin.Begin); string payload = (new StreamReader(stream)).ReadToEnd(); payload.Should().Be(expectedPayload); } }
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)"); }
protected override InMemoryMessage CreateRequestMessage(DataServiceClientRequestMessageArgs requestMessageArgs) { this.lastMessageCreated = base.CreateRequestMessage(requestMessageArgs); return(this.lastMessageCreated); }
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 byte[] CreateBigBatchRequest(int repeatCount) { MemoryStream stream = new MemoryStream(); IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream }; requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson); ODataMessageWriterSettings settings = new ODataMessageWriterSettings(); settings.BaseUri = new Uri(serviceDocumentUri); using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, settings)) { ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); // Each iteration generates a change set with two operations, followed by one top level operation. // Operations count in each iteration is three. for (int idx = 0; idx < repeatCount * 3; idx += 3) { batchWriter.WriteStartChangeset(); ODataBatchOperationRequestMessage createOperationMessage = batchWriter.CreateOperationRequestMessage( "PUT", new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "MySingleton")), idx.ToString()); using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(createOperationMessage)) { ODataWriter entryWriter = operationMessageWriter.CreateODataResourceWriter(); ODataResource entry = new ODataResource() { TypeName = "NS.Web", Properties = new[] { new ODataProperty() { Name = "WebId", Value = "webid_" + idx }, new ODataProperty() { Name = "Name", Value = this.aVeryLongString } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); } // A PATCH operation that depends on the preceding PUT operation. List <string> dependsOnIds = new List <string> { idx.ToString() }; ODataBatchOperationRequestMessage updateOperationMessage = batchWriter.CreateOperationRequestMessage( "PATCH", new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "$" + idx)), (idx + 1).ToString(), BatchPayloadUriOption.AbsoluteUri, dependsOnIds); // Verify that input values are copied into a new list. Assert.Equal(dependsOnIds, updateOperationMessage.DependsOnIds); Assert.NotSame(dependsOnIds, updateOperationMessage.DependsOnIds); using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(updateOperationMessage)) { var entryWriter = operationMessageWriter.CreateODataResourceWriter(); var entry = new ODataResource() { TypeName = "NS.Web", Properties = new[] { new ODataProperty() { Name = "WebId", Value = "webid_" + (idx + 1) } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); } Assert.Equal(createOperationMessage.GroupId, updateOperationMessage.GroupId); batchWriter.WriteEndChangeset(); ODataBatchOperationRequestMessage queryOperationMessage = batchWriter.CreateOperationRequestMessage( "GET", new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "MySingleton")), (idx + 2).ToString()); queryOperationMessage.SetHeader("Accept", "application/json;odata.metadata=full"); } batchWriter.WriteEndBatch(); stream.Position = 0; return(stream.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); } }
private byte[] ServiceReadReferenceUriBatchRequestAndWriteResponse(byte[] requestPayload) { IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(requestPayload) }; requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson); ODataMessageReaderSettings settings = new ODataMessageReaderSettings(); settings.BaseUri = new Uri(serviceDocumentUri); byte[] responseBytes = null; using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, settings, this.userModel)) { MemoryStream responseStream = new MemoryStream(); IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream }; // Client is expected to receive the response message in the same format as that is used in the request sent. responseMessage.SetHeader("Content-Type", batchContentTypeApplicationJson); using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage)) { ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); 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(); ODataBatchOperationResponseMessage response = batchWriter.CreateOperationResponseMessage(operationMessage.ContentId); if (operationMessage.Method == "PUT") { using (ODataMessageReader operationMessageReader = new ODataMessageReader( operationMessage, new ODataMessageReaderSettings(), this.userModel)) { ODataReader reader = operationMessageReader.CreateODataResourceReader(); Assert.NotNull(reader); } response.StatusCode = 201; response.SetHeader("Content-Type", "application/json;odata.metadata=none"); } else if (operationMessage.Method == "PATCH") { using (ODataMessageReader operationMessageReader = new ODataMessageReader( operationMessage, new ODataMessageReaderSettings(), this.userModel)) { ODataReader reader = operationMessageReader.CreateODataResourceReader(); Assert.NotNull(reader); } response.StatusCode = 204; } else if (operationMessage.Method == "GET") { response.StatusCode = 200; response.SetHeader("Content-Type", "application/json;"); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(); writerSettings.ODataUri.ServiceRoot = new Uri(serviceDocumentUri); using ( ODataMessageWriter operationMessageWriter = new ODataMessageWriter(response, writerSettings, this.userModel)) { ODataWriter entryWriter = operationMessageWriter.CreateODataResourceWriter(this.singleton, this.webType); ODataResource entry = new ODataResource() { TypeName = "NS.Web", Properties = new[] { new ODataProperty() { Name = "WebId", Value = -1 }, new ODataProperty() { Name = "Name", Value = aVeryLongString } } }; entryWriter.WriteStart(entry); entryWriter.WriteEnd(); } } break; case ODataBatchReaderState.ChangesetStart: // Set the group Id on the writer side to correlate with request. string atomicGroupId = batchReader.CurrentGroupId; batchWriter.WriteStartChangeset(atomicGroupId); break; case ODataBatchReaderState.ChangesetEnd: batchWriter.WriteEndChangeset(); break; } } batchWriter.WriteEndBatch(); responseStream.Position = 0; responseBytes = responseStream.ToArray(); } return(responseBytes); } }
private byte[] ClientWriteAsyncBatchRequest(BatchPayloadUriOption payloadUriOption) { var stream = new MemoryStream(); IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream }; requestMessage.SetHeader("Content-Type", batchContentType); using (var messageWriter = new ODataMessageWriter(requestMessage, new ODataMessageWriterSettings { BaseUri = new Uri(serviceDocumentUri) })) { var batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); // Write a query operation. var queryOperationMessage = batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), /*contentId*/ null, payloadUriOption); // 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", payloadUriOption); // Use a new message writer to write the body of this operation. using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage)) { var entryWriter = operationMessageWriter.CreateODataResourceWriter(); var entry = new ODataResource() { 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", payloadUriOption); using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage)) { var entryWriter = operationMessageWriter.CreateODataResourceWriter(); var entry = new ODataResource() { 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, payloadUriOption); batchWriter.WriteEndBatch(); stream.Position = 0; return(stream.ToArray()); } }
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 byte[] ServiceReadRequestAndWriterResponseForMultipartBatchVerifyDependsOnIds(string requestPayload, ODataVersion maxVersion) { byte[] responseBytes = null; IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(requestPayload)) }; requestMessage.SetHeader("Content-Type", batchContentTypeMultipartMime); ODataMessageReaderSettings settings = new ODataMessageReaderSettings { Version = maxVersion }; using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, settings, this.userModel)) { MemoryStream responseStream = new MemoryStream(); IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream }; // Client is expected to receive the response message in the same format as that is used in the request sent. responseMessage.SetHeader("Content-Type", batchContentTypeMultipartMime); using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage)) { ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); 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(); // Verify DependsOnIds are set correctly IEnumerable <string> dependsOnIds = operationMessage.DependsOnIds; switch (operationMessage.ContentId) { case "1": case "2A": Assert.True(dependsOnIds.Count() == 0); break; case "2B": Assert.True(dependsOnIds.SequenceEqual(new List <string> { "2A" })); break; case "2C": Assert.True(dependsOnIds.SequenceEqual(new List <string> { "2A", "2B" })); break; case "3": Assert.True(dependsOnIds.SequenceEqual(new List <string> { "1" })); break; default: break; } ODataBatchOperationResponseMessage response = batchWriter.CreateOperationResponseMessage(operationMessage.ContentId); if (operationMessage.Method == "PATCH") { response.StatusCode = 204; response.SetHeader("Content-Type", "application/json;odata.metadata=none"); } else if (operationMessage.Method == "PUT") { response.StatusCode = 201; response.SetHeader("Content-Type", "application/json;"); } break; case ODataBatchReaderState.ChangesetStart: batchWriter.WriteStartChangeset(); break; case ODataBatchReaderState.ChangesetEnd: batchWriter.WriteEndChangeset(); break; } } batchWriter.WriteEndBatch(); responseStream.Position = 0; responseBytes = responseStream.ToArray(); } return(responseBytes); } }
public void ShouldWriteDynamicNullableCollectionValuedProperty() { // setup model var model = new EdmModel(); var entityType = new EdmEntityType("NS", "EntityType", null, false, true); entityType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32); var container = new EdmEntityContainer("NS", "Container"); var entitySet = container.AddEntitySet("EntitySet", entityType); var complexType = new EdmComplexType("NS", "ComplexType"); complexType.AddStructuralProperty("Prop1", EdmPrimitiveTypeKind.Int32); complexType.AddStructuralProperty("Prop2", EdmPrimitiveTypeKind.Int32); model.AddElements(new IEdmSchemaElement[] { entityType, complexType, container }); // setup writer var stream = new MemoryStream(); var message = new InMemoryMessage { Stream = stream }; var settings = new ODataMessageWriterSettings { ODataUri = new ODataUri { ServiceRoot = new Uri("http://svc/") } }; var writer = new ODataMessageWriter((IODataResponseMessage)message, settings, model) .CreateODataResourceWriter(entitySet, entityType); // write payload writer.Write(new ODataResource { Properties = new[] { new ODataProperty { Name = "ID", Value = 1 }, new ODataProperty { Name = "DynamicPrimitive", Value = new ODataCollectionValue { TypeName = "Collection(Edm.Int64)", Items = new object[] { 1L, 2L, null } } } } }, () => writer .Write(new ODataNestedResourceInfo { Name = "DynamicComplex", IsCollection = true, }, () => writer .Write(new ODataResourceSet { TypeName = "Collection(NS.ComplexType)" }, () => writer .Write((ODataResource)null) .Write((ODataResource)null) .Write(new ODataResource { Properties = new[] { new ODataProperty { Name = "Prop1", Value = 1 }, new ODataProperty { Name = "Prop2", Value = 2 } } })))); var str = Encoding.UTF8.GetString(stream.ToArray()); Assert.Equal(str, "{" + "\"@odata.context\":\"http://svc/$metadata#EntitySet/$entity\"," + "\"ID\":1," + "\"[email protected]\":\"#Collection(Int64)\"," + "\"DynamicPrimitive\":[1,2,null]," + "\"[email protected]\":\"#Collection(NS.ComplexType)\"," + "\"DynamicComplex\":[null,null,{\"Prop1\":1,\"Prop2\":2}]" + "}"); }
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); } } } }
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); }
// 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>(); }
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 static void WriteCustomInstanceAnnotationToFeedAndEntry(string expectedPayload, ODataFormat format) { var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, EnableAtom = format == ODataFormat.Atom }; writerSettings.SetContentType(format); writerSettings.ODataUri = new ODataUri() { ServiceRoot = new Uri("http://www.example.com/") }; MemoryStream stream = new MemoryStream(); IODataResponseMessage messageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; messageToWrite.PreferenceAppliedHeader().AnnotationFilter = "Custom.*"; // Write payload using (var messageWriter = new ODataMessageWriter(messageToWrite, writerSettings, Model)) { var odataWriter = messageWriter.CreateODataFeedWriter(EntitySet, EntityType); // Add instance annotations to the feed. var feedToWrite = new ODataFeed { Id = new Uri("urn:feedId") }; feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.Int32Annotation", PrimitiveValue1)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.GuidAnnotation", PrimitiveValue2)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.Int32Annotation", PrimitiveValue1)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.GuidAnnotation", PrimitiveValue2)); // Writes instance annotations at the beginning of the feed odataWriter.WriteStart(feedToWrite); // Add instance annotations to the entry. var entryToWrite = new ODataEntry { Properties = new[] { new ODataProperty { Name = "ID", Value = 1 } } }; entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.ComplexAnnotation", ComplexValue1)); entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.ComplexAnnotation", ComplexValue1)); // Writes instance annotations at the beginning of the entry odataWriter.WriteStart(entryToWrite); // Add more instance annotations to the entry. entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.PrimitiveCollectionAnnotation", PrimitiveCollectionValue)); entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.PrimitiveCollectionAnnotation", PrimitiveCollectionValue)); // The writer remembers which instance annotations in the collection has been written // and only write out the unwritten ones since WriteStart() to the end of the entry. odataWriter.WriteEnd(); // Add more instance annotations to the feed. feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.ComplexCollectionAnnotation", ComplexCollectionValue)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.ComplexCollectionAnnotation", ComplexCollectionValue)); // The writer remembers which instance annotations in the collection has been written // and only write out the unwritten ones since WriteStart() to the end of the feed. odataWriter.WriteEnd(); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); if (format == ODataFormat.Atom) { // The <updated> element is computed dynamically, so we remove it from the both the baseline and the actual payload. payload = Regex.Replace(payload, "<updated>[^<]*</updated>", ""); expectedPayload = Regex.Replace(expectedPayload, "<updated>[^<]*</updated>", ""); } payload.Should().Be(expectedPayload); }
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); } } }