private void VerifyDateValueReader(string payload, string edmTypeName, object expectedResult) { IEdmModel model = new EdmModel(); IEdmPrimitiveTypeReference typeReference = new EdmPrimitiveTypeReference((IEdmPrimitiveType)model.FindType(edmTypeName), true); MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); object actualValue; using (ODataJsonLightInputContext inputContext = new ODataJsonLightInputContext( ODataFormat.Json, stream, JsonLightUtils.JsonLightStreamingMediaType, Encoding.UTF8, new ODataMessageReaderSettings(), /*readingResponse*/ true, /*synchronous*/ true, model, /*urlResolver*/ null)) { ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, typeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ true, /*insideComplexValue*/ false, /*propertyName*/ null); } actualValue.Should().Be(expectedResult, "payload ->{0}<- for type '{1}'", payload, edmTypeName); }
private void VerifyDateValueReader(string payload, string edmTypeName, object expectedResult) { IEdmModel model = new EdmModel(); IEdmPrimitiveTypeReference typeReference = new EdmPrimitiveTypeReference((IEdmPrimitiveType)model.FindType(edmTypeName), true); var messageInfo = new ODataMessageInfo { IsResponse = true, MediaType = JsonLightUtils.JsonLightStreamingMediaType, IsAsync = false, Model = new EdmModel(), }; object actualValue; using (var inputContext = new ODataJsonLightInputContext( new StringReader(payload), messageInfo, new ODataMessageReaderSettings())) { var deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, typeReference, /*propertyAndAnnotationCollector*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ true, /*insideResourceValue*/ false, /*propertyName*/ null); } actualValue.Should().Be(expectedResult, "payload ->{0}<- for type '{1}'", payload, edmTypeName); }
/// <summary> /// Reads a property value which occurs in the "error" object scope. /// </summary> /// <param name="error">The <see cref="ODataError"/> object to update with the data from this property value.</param> /// <param name="propertyName">The name of the property whose value is to be read.</param> /// <param name="duplicationPropertyNameChecker">DuplicatePropertyNamesChecker to use for extracting property annotations /// targetting any custom instance annotations on the error.</param> /// <remarks> /// Pre-Condition: any - The value of the property being read. /// Post-Condition: JsonNodeType.Property - The property after the one being read. /// JsonNodeType.EndObject - The end of the "error" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private void ReadPropertyValueInODataErrorObject(ODataError error, string propertyName, DuplicatePropertyNamesChecker duplicationPropertyNameChecker) { switch (propertyName) { case JsonConstants.ODataErrorCodeName: error.ErrorCode = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorCodeName); break; case JsonConstants.ODataErrorMessageName: error.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorMessageName); break; case JsonConstants.ODataErrorTargetName: error.Target = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorTargetName); break; case JsonConstants.ODataErrorDetailsName: error.Details = this.ReadDetails(); break; case JsonConstants.ODataErrorInnerErrorName: error.InnerError = this.ReadInnerError(0 /* recursionDepth */); break; default: // See if it's an instance annotation if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName)) { ODataJsonLightPropertyAndValueDeserializer valueDeserializer = new ODataJsonLightPropertyAndValueDeserializer(this.JsonLightInputContext); object typeName = null; var odataAnnotations = duplicationPropertyNameChecker.GetODataPropertyAnnotations(propertyName); if (odataAnnotations != null) { odataAnnotations.TryGetValue(ODataAnnotationNames.ODataType, out typeName); } var value = valueDeserializer.ReadNonEntityValue( typeName as string, null /*expectedValueTypeReference*/, null /*duplicatePropertiesNamesChecker*/, null /*collectionValidator*/, false /*validateNullValue*/, false /*isTopLevelPropertyValue*/, false /*insideComplexValue*/, propertyName); error.GetInstanceAnnotations().Add(new ODataInstanceAnnotation(propertyName, value.ToODataValue())); } else { // we only allow a 'code', 'message', 'target', 'details, and 'innererror' properties // in the value of the 'error' property or custom instance annotations throw new ODataException(Strings.ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty(propertyName)); } break; } }
private object WriteThenReadValue(object clrValue, IEdmTypeReference typeReference, ODataVersion version, bool isIeee754Compatible) { MemoryStream stream = new MemoryStream(); ODataMessageWriterSettings settings = new ODataMessageWriterSettings { Version = version }; settings.SetServiceDocumentUri(new Uri("http://odata.org/test/")); ODataMediaType mediaType = isIeee754Compatible ? new ODataMediaType("application", "json", new KeyValuePair <string, string>("IEEE754Compatible", "true")) : new ODataMediaType("application", "json"); using (ODataJsonLightOutputContext outputContext = new ODataJsonLightOutputContext( ODataFormat.Json, new NonDisposingStream(stream), mediaType, Encoding.UTF8, settings, /*writingResponse*/ true, /*synchronous*/ true, this.model, /*urlResolver*/ null)) { ODataJsonLightValueSerializer serializer = new ODataJsonLightValueSerializer(outputContext); serializer.WritePrimitiveValue(clrValue, typeReference); } stream.Position = 0; object actualValue; using (ODataJsonLightInputContext inputContext = new ODataJsonLightInputContext( ODataFormat.Json, stream, mediaType, Encoding.UTF8, new ODataMessageReaderSettings(), /*readingResponse*/ true, /*synchronous*/ true, this.model, /*urlResolver*/ null)) { ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(inputContext); deserializer.JsonReader.Read(); actualValue = deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, typeReference, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevel*/ true, /*insideComplexValue*/ false, /*propertyName*/ null); } return(actualValue); }
private static object ConvertFromResourceOrCollectionValue(string value, IEdmModel model, IEdmTypeReference typeReference) { ODataMessageReaderSettings settings = new ODataMessageReaderSettings(); settings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType; settings.ReadUntypedAsString = false; using (StringReader reader = new StringReader(value)) { ODataMessageInfo messageInfo = new ODataMessageInfo { MediaType = new ODataMediaType(MimeConstants.MimeApplicationType, MimeConstants.MimeJsonSubType), Model = model, IsResponse = false, IsAsync = false, MessageStream = null, }; using (ODataJsonLightInputContext context = new ODataJsonLightInputContext(reader, messageInfo, settings)) { 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 /*insideResourceValue*/, null /*propertyName*/); deserializer.ReadPayloadEnd(false); return(rawResult); } } }
/// <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) { ODataMessageReaderSettings settings = new ODataMessageReaderSettings(); 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); } } }
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); }
/// <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); } } }