private void VerifyPrimitiveValueRoundtrips(object clrValue, string edmTypeName, ODataVersion version, string description) { IEdmModel model = new EdmModel(); IEdmPrimitiveTypeReference typeReference = new EdmPrimitiveTypeReference((IEdmPrimitiveType)model.FindType(edmTypeName), true); MemoryStream stream = new MemoryStream(); using (ODataVerboseJsonOutputContext outputContext = new ODataVerboseJsonOutputContext( ODataFormat.VerboseJson, new NonDisposingStream(stream), Encoding.UTF8, new ODataMessageWriterSettings() { Version = version }, /*writingResponse*/ true, /*synchronous*/ true, model, /*urlResolver*/ null)) { ODataVerboseJsonPropertyAndValueSerializer serializer = new ODataVerboseJsonPropertyAndValueSerializer(outputContext); serializer.WritePrimitiveValue( clrValue, /*collectionValidator*/ null, typeReference); } stream.Position = 0; object actualValue; using (ODataVerboseJsonInputContext inputContext = new ODataVerboseJsonInputContext( ODataFormat.VerboseJson, stream, Encoding.UTF8, new ODataMessageReaderSettings(), version, /*readingResponse*/ true, /*synchronous*/ true, model, /*urlResolver*/ null)) { ODataVerboseJsonPropertyAndValueDeserializer deserializer = new ODataVerboseJsonPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( typeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*propertyName*/ null); } if (clrValue is byte[]) { ((byte[])actualValue).Should().Equal((byte[])clrValue, description); } else { actualValue.Should().Be(clrValue, description); } }
/// <summary> /// Converts the given string <paramref name="value"/> to an ODataComplexValue or ODataCollectionValue and returns it. /// Tries in both JSON light and Verbose JSON. /// </summary> /// <remarks>Does not handle primitive values.</remarks> /// <param name="value">Value to be deserialized.</param> /// <param name="version">ODataVersion to be compliant with.</param> /// <param name="model">Model to use for verification.</param> /// <param name="typeReference">Expected type reference from deserialization. If null, verification will be skipped.</param> /// <returns>An ODataComplexValue or ODataCollectionValue that results from the deserialization of <paramref name="value"/>.</returns> internal static object ConvertFromComplexOrCollectionValue(string value, ODataVersion version, IEdmModel model, IEdmTypeReference typeReference) { DebugUtils.CheckNoExternalCallers(); ODataMessageReaderSettings settings = new ODataMessageReaderSettings(); // Try read as JSON (light) so long as a custom model was provided if (model.IsUserModel()) { try { using (StringReader reader = new StringReader(value)) { using (ODataJsonLightInputContext context = new ODataJsonLightInputContext( ODataFormat.Json, reader, new MediaType(MimeConstants.MimeApplicationType, MimeConstants.MimeJsonSubType), settings, version, false /*readingResponse*/, true /*synchronous*/, model, null /*urlResolver*/, null /*payloadKindDetectionState*/)) { ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(context); // TODO: The way JSON array literals look in the URI is different that response payload with an array in it. // The fact that we have to manually setup the underlying reader shows this different in the protocol. // There is a discussion on if we should change this or not. deserializer.JsonReader.Read(); // Move to first thing object rawResult = deserializer.ReadNonEntityValue( null /*payloadTypeName*/, typeReference, null /*DuplicatePropertyNameChecker*/, null /*CollectionWithoutExpectedTypeValidator*/, true /*validateNullValue*/, false /*isTopLevelPropertyValue*/, false /*insideComplexValue*/, null /*propertyName*/); deserializer.ReadPayloadEnd(false); Debug.Assert(rawResult is ODataComplexValue || rawResult is ODataCollectionValue, "rawResult is ODataComplexValue || rawResult is ODataCollectionValue"); return(rawResult); } } } catch (ODataException) { // Swallow. We'll try reading it as Verbose JSON instead. // If an error occurs then, we'll surface that error message. // Since we shipped Verbose JSON only support in 5.0, it's nice to preserve the Verbose JSON error messages. } } // Read as Verbose JSON using (StringReader reader = new StringReader(value)) { using (ODataVerboseJsonInputContext context = new ODataVerboseJsonInputContext( ODataFormat.VerboseJson, reader, settings, version, false /*readingResponse*/, true /*synchronous*/, model, null /*urlResolver*/)) { ODataVerboseJsonPropertyAndValueDeserializer deserializer = new ODataVerboseJsonPropertyAndValueDeserializer(context); deserializer.ReadPayloadStart(false); object rawResult = deserializer.ReadNonEntityValue( typeReference, null /*DuplicatePropertyNameChecker*/, null /*CollectionWithoutExpectedTypeValidator*/, true /*validateNullValue*/, null /*propertyName*/); deserializer.ReadPayloadEnd(false); Debug.Assert(rawResult is ODataComplexValue || rawResult is ODataCollectionValue, "rawResult is ODataComplexValue || rawResult is ODataCollectionValue"); return(rawResult); } } }
private void VerifyPrimitiveValueRoundtrips(object clrValue, string edmTypeName, ODataVersion version, string description) { IEdmModel model = new EdmModel(); IEdmPrimitiveTypeReference typeReference = new EdmPrimitiveTypeReference((IEdmPrimitiveType)model.FindType(edmTypeName), true); MemoryStream stream = new MemoryStream(); using (ODataVerboseJsonOutputContext outputContext = new ODataVerboseJsonOutputContext( ODataFormat.VerboseJson, new NonDisposingStream(stream), Encoding.UTF8, new ODataMessageWriterSettings() { Version = version }, /*writingResponse*/ true, /*synchronous*/ true, model, /*urlResolver*/ null)) { ODataVerboseJsonPropertyAndValueSerializer serializer = new ODataVerboseJsonPropertyAndValueSerializer(outputContext); serializer.WritePrimitiveValue( clrValue, /*collectionValidator*/ null, typeReference); } stream.Position = 0; object actualValue; using (ODataVerboseJsonInputContext inputContext = new ODataVerboseJsonInputContext( ODataFormat.VerboseJson, stream, Encoding.UTF8, new ODataMessageReaderSettings(), version, /*readingResponse*/ true, /*synchronous*/ true, model, /*urlResolver*/ null)) { ODataVerboseJsonPropertyAndValueDeserializer deserializer = new ODataVerboseJsonPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( typeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*propertyName*/ null); } if (clrValue is byte[]) { ((byte[])actualValue).Should().Equal((byte[])clrValue, description); } else { actualValue.Should().Be(clrValue, description); } }