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; }
public void ParsingInstanceAnnotationInComplexValueShouldThrowOnReservedODataAnnotationNamesNotApplicableToComplexValues() { var model = new EdmModel(); var complexType = new EdmComplexType("TestNamespace", "Address"); model.AddElement(complexType); var complexTypeRef = new EdmComplexTypeReference(complexType, false); this.messageReaderSettings = new ODataMessageReaderSettings { ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*") }; ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("{\"@odata.count\":\"123\"}", model)); deserializer.JsonReader.Read(); Action action = () => deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, complexTypeRef, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ false, /*insideComplexValue*/ false, /*propertyName*/ null); action.ShouldThrow<ODataException>().WithMessage(ErrorStrings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties("odata.count")); }
public void ParsingInstanceAnnotationsInComplexValueShouldReadComplexValue() { var model = new EdmModel(); var complexType = new EdmComplexType("TestNamespace", "Address"); model.AddElement(complexType); var complexTypeRef = new EdmComplexTypeReference(complexType, false); this.messageReaderSettings = new ODataMessageReaderSettings { ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*") }; ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("{\"@Annotation.1\":true,\"@Annotation.2\":123,\"Annotation.3\":\"annotation\"}", model)); deserializer.JsonReader.Read(); ODataComplexValue complexValue = (ODataComplexValue)deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, complexTypeRef, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ false, /*insideComplexValue*/ false, /*propertyName*/ null); complexValue.InstanceAnnotations.Count.Should().Be(3); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(true), complexValue.InstanceAnnotations.Single(ia => ia.Name == "Annotation.1").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(123), complexValue.InstanceAnnotations.Single(ia => ia.Name == "Annotation.2").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue("annotation"), complexValue.InstanceAnnotations.Single(ia => ia.Name == "Annotation.3").Value); }
public void ParsingTypeDefinitionOverflowValueShouldFail() { var model = new EdmModel(); var uint16 = model.GetUInt16("NS", true); ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("123456789", model)); deserializer.JsonReader.Read(); Action action = () => deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, uint16, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ true, /*insideComplexValue*/ false, /*propertyName*/ null); action.ShouldThrow<ODataException>().WithMessage("Value '123456789' was either too large or too small for a 'NS.UInt16'."); }
public void ParsingInstanceAnnotationsInComplexPropertyShouldSkipBaseOnSettings() { var model = new EdmModel(); var complexType = new EdmComplexType("TestNamespace", "Address"); complexType.AddStructuralProperty("CountryRegion", EdmPrimitiveTypeKind.String); model.AddElement(complexType); var complexTypeRef = new EdmComplexTypeReference(complexType, false); ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("{\"[email protected]\":true,\"CountryRegion\":\"China\"}", model)); deserializer.JsonReader.Read(); ODataComplexValue complexValue = (ODataComplexValue)deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, complexTypeRef, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ false, /*insideComplexValue*/ false, /*propertyName*/ null); complexValue.Properties.First().InstanceAnnotations.Count.Should().Be(0); }
public void ParsingExpectedComplexPropertyActualNotShouldThrow() { var model = new EdmModel(); var complexType = new EdmComplexType("TestNamespace", "Address"); model.AddElement(complexType); var complexTypeRef = new EdmComplexTypeReference(complexType, false); ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("\"CountryRegion\":\"China\"", model)); deserializer.JsonReader.Read(); Action action = () => deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, complexTypeRef, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ false, /*insideComplexValue*/ false, /*propertyName*/ "Home"); action.ShouldThrow<ODataException>().WithMessage( string.Format(CultureInfo.InvariantCulture, "The property with name '{0}' was found with a value node of type '{1}'; however, a complex value of type '{2}' was expected.", "Home", "PrimitiveValue", "TestNamespace.Address")); }
public void ParsingTypeDefinitionValueOfIncompatibleTypeShouldFail() { var model = new EdmModel(); var uint32 = model.GetUInt32("NS", true); ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("\"123\"", model)); deserializer.JsonReader.Read(); Action action = () => deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, uint32, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ true, /*insideComplexValue*/ false, /*propertyName*/ null); action.ShouldThrow<ODataException>().WithMessage(ErrorStrings.ODataJsonReaderUtils_ConflictBetweenInputFormatAndParameter("Edm.Int64")); }
public void ParsingInstanceAnnotationsInComplexValueShouldSkipBaseOnSettings() { var model = new EdmModel(); var complexType = new EdmComplexType("TestNamespace", "Address"); model.AddElement(complexType); var complexTypeRef = new EdmComplexTypeReference(complexType, false); this.messageReaderSettings = new ODataMessageReaderSettings(); ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("{\"@Annotation.1\":true,\"@Annotation.2\":123,\"Annotation.3\":\"annotation\"}", model)); deserializer.JsonReader.Read(); ODataComplexValue complexValue = (ODataComplexValue)deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, complexTypeRef, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ false, /*insideComplexValue*/ false, /*propertyName*/ null); complexValue.InstanceAnnotations.Count.Should().Be(0); }
public void ParsingInstanceAnnotationsInDisorderInComplexValueShouldPass() { var model = new EdmModel(); var complexType = new EdmComplexType("TestNamespace", "Address"); complexType.AddStructuralProperty("CountryRegion", EdmPrimitiveTypeKind.String); model.AddElement(complexType); var complexTypeRef = new EdmComplexTypeReference(complexType, false); this.messageReaderSettings = new ODataMessageReaderSettings { ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*") }; ODataJsonLightPropertyAndValueDeserializer deserializer = new ODataJsonLightPropertyAndValueDeserializer(this.CreateJsonLightInputContext("{\"@Annotation.1\":true,\"@Annotation.2\":123,\"CountryRegion\":\"China\",\"@Annotation.3\":\"annotation\"}", model)); deserializer.JsonReader.Read(); Action action = () => deserializer.ReadNonEntityValue( /*payloadTypeName*/ null, complexTypeRef, /*duplicatePropertyNamesChecker*/ null, /*collectionValidator*/ null, /*validateNullValue*/ true, /*isTopLevelPropertyValue*/ false, /*insideComplexValue*/ false, /*propertyName*/ null); action.ShouldNotThrow(); }
/// <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 void VerifyTimeOfDayValueReader(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); }
/// <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="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, IEdmModel model, IEdmTypeReference typeReference) { ODataMessageReaderSettings settings = new ODataMessageReaderSettings(); using (StringReader reader = new StringReader(value)) { using (ODataJsonLightInputContext context = new ODataJsonLightInputContext( ODataFormat.Json, reader, new ODataMediaType(MimeConstants.MimeApplicationType, MimeConstants.MimeJsonSubType), settings, false /*readingResponse*/, true /*synchronous*/, model, null /*urlResolver*/)) { 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; } } }