/// <summary> /// Write a literal value in JSON Light format. /// </summary> /// <param name="model">EDM Model to use for validation and type lookups.</param> /// <param name="messageWriterSettings">Settings to use when writing.</param> /// <param name="textWriter">TextWriter to use as the output for the value.</param> /// <param name="writeValue">Delegate to use to actually write the value.</param> private static void WriteJsonLightLiteral(IEdmModel model, ODataMessageWriterSettings messageWriterSettings, TextWriter textWriter, Action <ODataJsonLightValueSerializer> writeValue) { // Calling dispose since it's the right thing to do, but when created from a custom-built TextWriter // the output context Dispose will not actually dispose anything, it will just cleanup itself. using (ODataJsonLightOutputContext jsonOutputContext = new ODataJsonLightOutputContext(ODataFormat.Json, textWriter, messageWriterSettings, model)) { ODataJsonLightValueSerializer jsonLightValueSerializer = new ODataJsonLightValueSerializer(jsonOutputContext); writeValue(jsonLightValueSerializer); jsonLightValueSerializer.AssertRecursionDepthIsZero(); } }
private async Task <string> SetupJsonLightOutputContextAndRunTestAsync( Func <ODataJsonLightOutputContext, Task> func, bool writingResponse = true) { var messageInfo = CreateMessageInfo(this.model, /*synchronous*/ true, writingResponse); var jsonLightOutputContext = new ODataJsonLightOutputContext(messageInfo, this.messageWriterSettings); await func(jsonLightOutputContext); this.stream.Position = 0; return(await new StreamReader(this.stream).ReadToEndAsync()); }
/// <summary> /// Serialize the given property as a non-top-level property in JSON Light. /// </summary> /// <param name="odataProperty">The property to serialize.</param> /// <returns>A string of JSON text, where the given ODataProperty has been serialized and wrapped in a JSON object.</returns> private string SerializeComplexResource(IEdmStructuredType owningType, ODataResource complex) { MemoryStream outputStream = new MemoryStream(); ODataJsonLightOutputContext jsonLightOutputContext = this.CreateJsonLightOutputContext(outputStream); var odataWriter = jsonLightOutputContext.CreateODataResourceWriter(null, owningType); odataWriter.WriteStart(complex); odataWriter.WriteEnd(); odataWriter.Flush(); outputStream.Position = 0; string result = new StreamReader(outputStream).ReadToEnd(); return(result); }
private async Task <string> SetupSerializerAndRunTestAsync(Func <ODataJsonLightPropertySerializer, Task> func) { MemoryStream outputStream = new MemoryStream(); ODataJsonLightOutputContext jsonLightOutputContext = this.CreateJsonLightOutputContext(outputStream); var jsonLightPropertySerializer = new ODataJsonLightPropertySerializer(jsonLightOutputContext, /* initContextUriBuilder */ true); await func(jsonLightPropertySerializer); await jsonLightPropertySerializer.JsonLightOutputContext.FlushAsync(); await jsonLightPropertySerializer.AsynchronousJsonWriter.FlushAsync(); outputStream.Position = 0; return(await new StreamReader(outputStream).ReadToEndAsync()); }
private async Task <string> SetupJsonLightResourceSerializerAndRunTestAsync(Func <ODataJsonLightResourceSerializer, Task> func) { ODataJsonLightOutputContext jsonLightOutputContext = this.CreateJsonLightOutputContext(); var jsonLightResourceSerializer = new ODataJsonLightResourceSerializer(jsonLightOutputContext); await jsonLightResourceSerializer.AsynchronousJsonWriter.StartObjectScopeAsync(); await func(jsonLightResourceSerializer); await jsonLightResourceSerializer.JsonLightOutputContext.FlushAsync(); await jsonLightResourceSerializer.AsynchronousJsonWriter.FlushAsync(); this.stream.Position = 0; return(await new StreamReader(this.stream).ReadToEndAsync()); }
private void WriteEntryAndValidatePayloadWithoutModel(ODataResource entry, string expectedPayload, bool writingResponse = true, bool setMetadataDocumentUri = true) { MemoryStream stream = new MemoryStream(); ODataJsonLightOutputContext outputContext = CreateJsonLightOutputContext(stream, writingResponse, this.userModel, setMetadataDocumentUri ? this.serviceDocumentUri : null); ODataResourceSerializationInfo serializationInfo = new ODataResourceSerializationInfo { NavigationSourceName = "MySingleton", NavigationSourceEntityTypeName = "NS.Web", NavigationSourceKind = EdmNavigationSourceKind.Singleton, }; entry.SerializationInfo = serializationInfo; ODataJsonLightWriter writer = new ODataJsonLightWriter(outputContext, /*navigationSource*/ null, /*entityType*/ null, /*writingFeed*/ false); WriteEntryAndValidatePayload(entry, stream, writer, expectedPayload); }
public async Task WriteSpatialCollectionPropertyForInjectedJsonWriterFactoryAsync() { var messageInfo = CreateMessageInfo(this.model, /*synchronous*/ true, /*writingResponse*/ true); messageInfo.Container = ContainerBuilderHelper.BuildContainer(builder => { builder.AddService <IJsonWriterFactory>(ServiceLifetime.Singleton, _ => new DefaultJsonWriterFactory()); builder.AddService <IJsonWriterFactoryAsync>(ServiceLifetime.Singleton, _ => new DefaultJsonWriterFactory()); }); var jsonLightOutputContext = new ODataJsonLightOutputContext(messageInfo, this.messageWriterSettings); var geographyCollection = new object[] { GeographyFactory.Point(33.1, -110.0).Build(), GeographyFactory.LineString(33.1, -110.0).LineTo(35.97, -110).Build(), GeographyFactory.MultiPoint().Point(10.2, 11.2).Point(11.9, 11.6).Build() }; var geographyCollectionProperty = new ODataProperty { Name = "GeographyCollectionProperty", Value = new ODataCollectionValue { TypeName = "Collection(Edm.Geography)", Items = geographyCollection } }; await jsonLightOutputContext.WritePropertyAsync(geographyCollectionProperty); await jsonLightOutputContext.FlushAsync(); this.stream.Position = 0; var result = await new StreamReader(this.stream).ReadToEndAsync(); Assert.Equal( "{\"@odata.context\":\"http://tempuri.org/$metadata#Collection(Edm.Geography)\"," + "\"value\":[" + "{\"type\":\"Point\",\"coordinates\":[-110.0,33.1],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}," + "{\"type\":\"LineString\",\"coordinates\":[[-110.0,33.1],[-110.0,35.97]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}," + "{\"type\":\"MultiPoint\",\"coordinates\":[[11.2,10.2],[11.6,11.9]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}" + "]}", result); }
private static ODataJsonLightServiceDocumentSerializer CreateODataJsonLightServiceDocumentSerializer(MemoryStream memoryStream, IODataPayloadUriConverter urlResolver = null) { var model = new EdmModel(); var messageWriterSettings = new ODataMessageWriterSettings(); var mainModel = TestUtils.WrapReferencedModelsToMainModel(model); var messageInfo = new ODataMessageInfo { MessageStream = memoryStream, MediaType = new ODataMediaType("application", "json"), Encoding = Encoding.UTF8, IsResponse = false, IsAsync = false, Model = mainModel, PayloadUriConverter = urlResolver }; var jsonLightOutputContext = new ODataJsonLightOutputContext(messageInfo, messageWriterSettings); return(new ODataJsonLightServiceDocumentSerializer(jsonLightOutputContext)); }
/// <summary> /// Convert to a literal value in JSON Light format. /// </summary> /// <param name="model">EDM Model to use for validation and type lookups.</param> /// <param name="writeAction">Delegate to use to actually write the value.</param> /// <returns>The literal value string.</returns> private static string ConverToJsonLightLiteral(IEdmModel model, Action <ODataOutputContext> writeAction) { using (MemoryStream stream = new MemoryStream()) { ODataMessageWriterSettings messageWriterSettings = new ODataMessageWriterSettings() { Version = ODataVersion.V4, Indent = false }; ODataMediaType mediaType = new ODataMediaType(MimeConstants.MimeApplicationType, MimeConstants.MimeJsonSubType); using (ODataJsonLightOutputContext jsonOutputContext = new ODataJsonLightOutputContext(ODataFormat.Json, stream, mediaType, Encoding.UTF8, messageWriterSettings, false, true, model, null)) { writeAction(jsonOutputContext); stream.Position = 0; return(new StreamReader(stream).ReadToEnd()); } } }
/// <summary> /// Serialize the given property as a non-top-level property in JSON Light. /// </summary> /// <param name="odataProperty">The property to serialize.</param> /// <returns>A string of JSON text, where the given ODataProperty has been serialized and wrapped in a JSON object.</returns> private string SerializeProperty(IEdmStructuredType owningType, ODataProperty odataProperty) { MemoryStream outputStream = new MemoryStream(); ODataJsonLightOutputContext jsonLightOutputContext = this.CreateJsonLightOutputContext(outputStream); var serializer = new ODataJsonLightPropertySerializer(jsonLightOutputContext); jsonLightOutputContext.JsonWriter.StartObjectScope(); serializer.WriteProperties( owningType, new[] { odataProperty }, /*isComplexValue*/ false, new NullDuplicatePropertyNameChecker()); jsonLightOutputContext.JsonWriter.EndObjectScope(); jsonLightOutputContext.Flush(); outputStream.Position = 0; string result = new StreamReader(outputStream).ReadToEnd(); return(result); }
private ODataJsonLightValueSerializer CreateODataJsonLightValueSerializer(bool writingResponse, IServiceProvider container = null, bool isAsync = false) { var messageInfo = new ODataMessageInfo { MessageStream = this.stream, MediaType = new ODataMediaType("application", "json"), #if NETCOREAPP1_1 Encoding = Encoding.GetEncoding(0), #else Encoding = Encoding.Default, #endif IsResponse = writingResponse, IsAsync = isAsync, Model = this.model, Container = container }; var context = new ODataJsonLightOutputContext(messageInfo, this.settings); return(new ODataJsonLightValueSerializer(context)); }
/// <summary> /// Write a literal value in JSON Light format. /// </summary> /// <param name="model">EDM Model to use for validation and type lookups.</param> /// <param name="messageWriterSettings">Settings to use when writing.</param> /// <param name="textWriter">TextWriter to use as the output for the value.</param> /// <param name="writeValue">Delegate to use to actually write the value.</param> private static void WriteJsonLightLiteral(IEdmModel model, ODataMessageWriterSettings messageWriterSettings, TextWriter textWriter, Action <ODataJsonLightValueSerializer> writeValue) { // Calling dispose since it's the right thing to do, but when created from a custom-built TextWriter // the output context Dispose will not actually dispose anything, it will just cleanup itself. // TODO: URI parser will also support DI container in the future but set the container to null at this moment. ODataMessageInfo messageInfo = new ODataMessageInfo { Model = model, IsAsync = false, IsResponse = false }; using (ODataJsonLightOutputContext jsonOutputContext = new ODataJsonLightOutputContext(textWriter, messageInfo, messageWriterSettings)) { ODataJsonLightValueSerializer jsonLightValueSerializer = new ODataJsonLightValueSerializer(jsonOutputContext); writeValue(jsonLightValueSerializer); jsonLightValueSerializer.AssertRecursionDepthIsZero(); } }
private string SerializeProperty(ODataProperty odataProperty) { MemoryStream outputStream = new MemoryStream(); ODataJsonLightOutputContext jsonLightOutputContext = this.CreateJsonLightOutputContext(outputStream); var serializer = new ODataJsonLightPropertySerializer(jsonLightOutputContext); jsonLightOutputContext.JsonWriter.StartObjectScope(); serializer.WriteProperties( this.entityType, new[] { odataProperty }, /*isComplexValue*/ false, new DuplicatePropertyNamesChecker(allowDuplicateProperties: true, isResponse: true), ProjectedPropertiesAnnotation.AllProjectedPropertiesInstance); jsonLightOutputContext.JsonWriter.EndObjectScope(); jsonLightOutputContext.Flush(); outputStream.Position = 0; string result = new StreamReader(outputStream).ReadToEnd(); return(result); }
private static ODataJsonLightSerializer GetSerializer(Stream stream, string jsonpFunctionName = null, bool nometadata = false, bool setMetadataDocumentUri = true) { var model = new EdmModel(); var complexType = new EdmComplexType("ns", "ErrorDetails"); //var collectionType = new EdmCollectionType(new EdmComplexTypeReference(complexType, false)); model.AddElement(complexType); var settings = new ODataMessageWriterSettings { JsonPCallback = jsonpFunctionName, DisableMessageStreamDisposal = true, Version = ODataVersion.V4 }; if (setMetadataDocumentUri) { settings.SetServiceDocumentUri(new Uri("http://example.com")); } ODataMediaType mediaType = nometadata ? new ODataMediaType("application", "json", new KeyValuePair <string, string>("odata", "none")) : new ODataMediaType("application", "json"); IEdmModel mainModel = TestUtils.WrapReferencedModelsToMainModel(model); var context = new ODataJsonLightOutputContext(ODataFormat.Json, stream, mediaType, Encoding.Default, settings, true, true, mainModel, null); return(new ODataJsonLightSerializer(context, setMetadataDocumentUri)); }
/// <summary> /// Write a literal value in JSON Light format. /// </summary> /// <param name="model">EDM Model to use for validation and type lookups.</param> /// <param name="messageWriterSettings">Settings to use when writing.</param> /// <param name="textWriter">TextWriter to use as the output for the value.</param> /// <param name="writeValue">Delegate to use to actually write the value.</param> /// <param name="isResourceValue">We want to pass the <see cref="IDuplicatePropertyNameChecker"/> instance to the Action delegate when writing Resource value but not Collection value.</param> private static void WriteJsonLightLiteral(IEdmModel model, ODataMessageWriterSettings messageWriterSettings, TextWriter textWriter, Action <ODataJsonLightValueSerializer, IDuplicatePropertyNameChecker> writeValue, bool isResourceValue = true) { IEnumerable <KeyValuePair <string, string> > parameters = new Dictionary <string, string> { { MimeConstants.MimeIeee754CompatibleParameterName, messageWriterSettings.IsIeee754Compatible.ToString() } }; ODataMediaType mediaType = new ODataMediaType(MimeConstants.MimeApplicationType, MimeConstants.MimeJsonSubType, parameters); // Calling dispose since it's the right thing to do, but when created from a custom-built TextWriter // the output context Dispose will not actually dispose anything, it will just cleanup itself. // TODO: URI parser will also support DI container in the future but set the container to null at this moment. ODataMessageInfo messageInfo = new ODataMessageInfo { Model = model, IsAsync = false, IsResponse = false, MediaType = mediaType }; using (ODataJsonLightOutputContext jsonOutputContext = new ODataJsonLightOutputContext(textWriter, messageInfo, messageWriterSettings)) { ODataJsonLightValueSerializer jsonLightValueSerializer = new ODataJsonLightValueSerializer(jsonOutputContext); if (!isResourceValue) { writeValue(jsonLightValueSerializer, null); } else { IDuplicatePropertyNameChecker duplicatePropertyNameChecker = jsonLightValueSerializer.GetDuplicatePropertyNameChecker(); writeValue(jsonLightValueSerializer, duplicatePropertyNameChecker); jsonLightValueSerializer.ReturnDuplicatePropertyNameChecker(duplicatePropertyNameChecker); } jsonLightValueSerializer.AssertRecursionDepthIsZero(); } }
private static string WriteInstanceAnnotation(ODataInstanceAnnotation instanceAnnotation, IEdmModel model) { var stringWriter = new StringWriter(); var outputContext = new ODataJsonLightOutputContext( ODataFormat.Json, stringWriter, new ODataMessageWriterSettings { Version = ODataVersion.V4, ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*") }, model); var valueSerializer = new ODataJsonLightValueSerializer(outputContext); // The JSON Writer will complain if there is no active scope, so start an object scope. valueSerializer.JsonWriter.StartObjectScope(); var instanceAnnotationWriter = new JsonLightInstanceAnnotationWriter(valueSerializer, new JsonMinimalMetadataTypeNameOracle()); // The method under test. instanceAnnotationWriter.WriteInstanceAnnotation(instanceAnnotation); valueSerializer.JsonWriter.EndObjectScope(); return(stringWriter.ToString()); }
private void TestInit(IEdmModel userModel = null, bool fullMetadata = false) { this.stream = new MemoryStream(); this.outputContext = CreateJsonLightOutputContext(this.stream, userModel, fullMetadata); }
private object WriteThenReadValue(object clrValue, IEdmTypeReference typeReference, ODataVersion version, bool isIeee754Compatible) { var stream = new MemoryStream(); var settings = new ODataMessageWriterSettings { Version = version }; settings.SetServiceDocumentUri(new Uri("http://odata.org/test/")); var mediaType = isIeee754Compatible ? new ODataMediaType("application", "json", new KeyValuePair <string, string>("IEEE754Compatible", "true")) : new ODataMediaType("application", "json"); var messageInfoForWriter = new ODataMessageInfo { MessageStream = new NonDisposingStream(stream), MediaType = mediaType, Encoding = Encoding.UTF8, IsResponse = true, IsAsync = false, Model = this.model, Container = this.container }; using (var outputContext = new ODataJsonLightOutputContext(messageInfoForWriter, settings)) { var serializer = new ODataJsonLightValueSerializer(outputContext); serializer.WritePrimitiveValue(clrValue, typeReference); } stream.Position = 0; var messageInfoForReader = new ODataMessageInfo { Encoding = Encoding.UTF8, IsResponse = true, MediaType = mediaType, IsAsync = false, Model = this.model, MessageStream = stream, Container = this.container }; object actualValue; using (var inputContext = new ODataJsonLightInputContext( messageInfoForReader, new ODataMessageReaderSettings())) { var deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, typeReference, /*propertyAndAnnotationCollector*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevel*/ true, /*insideResourceValue*/ false, /*propertyName*/ null); } return(actualValue); }
private object WriteAsUntypedThenReadValue(string value, IEdmTypeReference typeReference, ODataVersion version) { var stream = new MemoryStream(); var settings = new ODataMessageWriterSettings { Version = version }; settings.SetServiceDocumentUri(new Uri("http://tempuri.org/")); var mediaType = new ODataMediaType("application", "json"); var messageInfoForWriter = new ODataMessageInfo { MessageStream = new NonDisposingStream(stream), MediaType = mediaType, Encoding = Encoding.UTF8, IsResponse = true, IsAsync = false, Model = this.model, Container = this.container }; using (var outputContext = new ODataJsonLightOutputContext(messageInfoForWriter, settings)) { var serializer = new ODataJsonLightValueSerializer(outputContext); // Writing the value as untyped it remains in its original form serializer.WriteUntypedValue(new ODataUntypedValue { RawValue = value }); } stream.Position = 0; var messageInfoForReader = new ODataMessageInfo { Encoding = Encoding.UTF8, IsResponse = true, MediaType = mediaType, IsAsync = false, Model = this.model, MessageStream = stream, Container = this.container }; object actualValue; using (var inputContext = new ODataJsonLightInputContext( messageInfoForReader, new ODataMessageReaderSettings())) { var deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, typeReference, /*propertyAndAnnotationCollector*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevel*/ true, /*insideResourceValue*/ false, /*propertyName*/ null); } return(actualValue); }
private void VerifyComplexRoundtrip(string propertyName, ODataResourceSet resourceSet, params ODataResource[] resources) { var nestedResourceInfo = new ODataNestedResourceInfo() { Name = propertyName, IsCollection = resourceSet != null }; var entry = new ODataResource() { TypeName = "NS.Student" }; ODataMessageWriterSettings settings = new ODataMessageWriterSettings { Version = ODataVersion.V4 }; MemoryStream stream = new MemoryStream(); var messageInfoForWriter = new ODataMessageInfo { MessageStream = new NonDisposingStream(stream), MediaType = new ODataMediaType("application", "json"), Encoding = Encoding.UTF8, IsResponse = false, IsAsync = false, Model = model }; using (var outputContext = new ODataJsonLightOutputContext(messageInfoForWriter, settings)) { var jsonLightWriter = new ODataJsonLightWriter(outputContext, this.studentSet, this.studentInfo, /*writingFeed*/ false); jsonLightWriter.WriteStart(entry); jsonLightWriter.WriteStart(nestedResourceInfo); if (resourceSet != null) { jsonLightWriter.WriteStart(resourceSet); } foreach (var value in resources) { jsonLightWriter.WriteStart(value); jsonLightWriter.WriteEnd(); } if (resourceSet != null) { jsonLightWriter.WriteEnd(); } jsonLightWriter.WriteEnd(); jsonLightWriter.WriteEnd(); } stream.Position = 0; List <ODataResource> actualResources = new List <ODataResource>(); var messageInfoForReader = new ODataMessageInfo { Encoding = Encoding.UTF8, IsResponse = false, MediaType = JsonLightUtils.JsonLightStreamingMediaType, IsAsync = false, Model = model, MessageStream = stream }; using (var inputContext = new ODataJsonLightInputContext(messageInfoForReader, new ODataMessageReaderSettings())) { var jsonLightReader = new ODataJsonLightReader(inputContext, this.studentSet, this.studentInfo, /*readingFeed*/ false); while (jsonLightReader.Read()) { if (jsonLightReader.State == ODataReaderState.ResourceEnd) { actualResources.Add(jsonLightReader.Item as ODataResource); } } } var count = actualResources.Count; actualResources.RemoveAt(count - 1); TestUtils.AssertODataResourceSetAreEqual(actualResources, resources.ToList()); }
public MockJsonLightValueSerializer(ODataJsonLightOutputContext outputContext, bool initContextUriBuilder = false) : base(outputContext, initContextUriBuilder) { }
private void VerifyNonPrimitiveTypeRoundtrip(object value, string propertyName) { var properties = new[] { new ODataProperty { Name = propertyName, Value = value } }; var entry = new ODataResource() { TypeName = "NS.Student", Properties = properties }; var stream = new MemoryStream(); var messageInfoForWriter = new ODataMessageInfo { MessageStream = new NonDisposingStream(stream), MediaType = new ODataMediaType("application", "json"), Encoding = Encoding.UTF8, IsResponse = false, IsAsync = false, Model = model }; var settings = new ODataMessageWriterSettings { Version = ODataVersion.V4, Validations = ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType }; using (var outputContext = new ODataJsonLightOutputContext(messageInfoForWriter, settings)) { var jsonLightWriter = new ODataJsonLightWriter(outputContext, this.studentSet, this.studentInfo, /*writingFeed*/ false); jsonLightWriter.WriteStart(entry); jsonLightWriter.WriteEnd(); } stream.Position = 0; object actualValue = null; var messageInfoForReader = new ODataMessageInfo { Encoding = Encoding.UTF8, IsResponse = false, MediaType = JsonLightUtils.JsonLightStreamingMediaType, IsAsync = false, Model = model, MessageStream = stream }; using (var inputContext = new ODataJsonLightInputContext(messageInfoForReader, new ODataMessageReaderSettings())) { var jsonLightReader = new ODataJsonLightReader(inputContext, this.studentSet, this.studentInfo, /*readingFeed*/ false); while (jsonLightReader.Read()) { if (jsonLightReader.State == ODataReaderState.ResourceEnd) { ODataResource entryOut = jsonLightReader.Item as ODataResource; actualValue = entryOut.Properties.Single(p => p.Name == propertyName).ODataValue; } } } TestUtils.AssertODataValueAreEqual(actualValue as ODataValue, value as ODataValue); }
private void TestInit(IEdmModel userModel = null) { this.stream = new MemoryStream(); this.outputContext = CreateJsonLightOutputContext(this.stream, userModel); }