/// <summary> /// Tries to read a null value from the JSON reader. /// </summary> /// <param name="jsonReader">The JSON reader to read from.</param> /// <param name="inputContext">The input context with all the settings.</param> /// <param name="expectedTypeReference">The expected type reference of the value.</param> /// <param name="validateNullValue">true to validate null values; otherwise false.</param> /// <param name="propertyName">The name of the property whose value is being read, if applicable (used for error reporting).</param> /// <param name="isDynamicProperty">Indicates whether the property is dynamic or unknown.</param> /// <returns>true if a null value could be read from the JSON reader; otherwise false.</returns> /// <remarks>If the method detects a null value it will read it (position the reader after the null value); /// otherwise the reader does not move.</remarks> internal static bool TryReadNullValue( BufferingJsonReader jsonReader, ODataInputContext inputContext, IEdmTypeReference expectedTypeReference, bool validateNullValue, string propertyName, bool?isDynamicProperty = null) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(inputContext != null, "inputContext != null"); if (jsonReader.NodeType == JsonNodeType.PrimitiveValue && jsonReader.Value == null) { jsonReader.ReadNext(); // NOTE: when reading a null value we will never ask the type resolver (if present) to resolve the // type; we always fall back to the expected type. ReaderValidationUtils.ValidateNullValue( inputContext.Model, expectedTypeReference, inputContext.MessageReaderSettings, validateNullValue, inputContext.Version, propertyName, isDynamicProperty); return(true); } return(false); }
/// <summary> /// Try and parse spatial type from the json payload. /// </summary> /// <param name="jsonReader">The JSON reader to read from.</param> /// <param name="insideJsonObjectValue">true if the reader is positioned on the first property of the value which is a JSON Object /// (or the second property if the first one was odata.type).</param> /// <param name="inputContext">The input context with all the settings.</param> /// <param name="expectedValueTypeReference">Expected edm property type.</param> /// <param name="validateNullValue">true to validate null values; otherwise false.</param> /// <param name="recursionDepth">The recursion depth to start with.</param> /// <param name="propertyName">The name of the property whose value is being read, if applicable (used for error reporting).</param> /// <returns>An instance of the spatial type.</returns> internal static ISpatial ReadSpatialValue( BufferingJsonReader jsonReader, bool insideJsonObjectValue, ODataInputContext inputContext, IEdmPrimitiveTypeReference expectedValueTypeReference, bool validateNullValue, int recursionDepth, string propertyName) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(inputContext != null, "inputContext != null"); Debug.Assert(expectedValueTypeReference != null, "expectedValueTypeReference != null"); Debug.Assert(expectedValueTypeReference.IsSpatial(), "TryParseSpatialType must be called only with spatial types"); // Spatial value can be either null constant or a JSON object // If it's a null primitive value, report a null value. if (!insideJsonObjectValue && TryReadNullValue(jsonReader, inputContext, expectedValueTypeReference, validateNullValue, propertyName)) { return null; } Microsoft.Spatial.ISpatial spatialValue = null; if (insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.StartObject) { IDictionary<string, object> jsonObject = ReadObjectValue(jsonReader, insideJsonObjectValue, inputContext, recursionDepth); Microsoft.Spatial.GeoJsonObjectFormatter jsonObjectFormatter = Microsoft.Spatial.SpatialImplementation.CurrentImplementation.CreateGeoJsonObjectFormatter(); if (EdmLibraryExtensions.IsGeographyType(expectedValueTypeReference)) { spatialValue = jsonObjectFormatter.Read<Microsoft.Spatial.Geography>(jsonObject); } else { spatialValue = jsonObjectFormatter.Read<Microsoft.Spatial.Geometry>(jsonObject); } } if (spatialValue == null) { throw new ODataException(ODataErrorStrings.ODataJsonReaderCoreUtils_CannotReadSpatialPropertyValue); } return spatialValue; }
/// <summary> /// Try and parse spatial type from the json payload. /// </summary> /// <param name="jsonReader">The JSON reader to read from.</param> /// <param name="insideJsonObjectValue">true if the reader is positioned on the first property of the value which is a JSON Object /// (or the second property if the first one was odata.type).</param> /// <param name="inputContext">The input context with all the settings.</param> /// <param name="expectedValueTypeReference">Expected edm property type.</param> /// <param name="validateNullValue">true to validate null values; otherwise false.</param> /// <param name="recursionDepth">The recursion depth to start with.</param> /// <param name="propertyName">The name of the property whose value is being read, if applicable (used for error reporting).</param> /// <returns>An instance of the spatial type.</returns> internal static ISpatial ReadSpatialValue( BufferingJsonReader jsonReader, bool insideJsonObjectValue, ODataInputContext inputContext, IEdmPrimitiveTypeReference expectedValueTypeReference, bool validateNullValue, int recursionDepth, string propertyName) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(inputContext != null, "inputContext != null"); Debug.Assert(expectedValueTypeReference != null, "expectedValueTypeReference != null"); Debug.Assert(expectedValueTypeReference.IsSpatial(), "TryParseSpatialType must be called only with spatial types"); // Spatial value can be either null constant or a JSON object // If it's a null primitive value, report a null value. if (!insideJsonObjectValue && TryReadNullValue(jsonReader, inputContext, expectedValueTypeReference, validateNullValue, propertyName)) { return(null); } Microsoft.Spatial.ISpatial spatialValue = null; if (insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.StartObject) { IDictionary <string, object> jsonObject = ReadObjectValue(jsonReader, insideJsonObjectValue, inputContext, recursionDepth); Microsoft.Spatial.GeoJsonObjectFormatter jsonObjectFormatter = Microsoft.Spatial.SpatialImplementation.CurrentImplementation.CreateGeoJsonObjectFormatter(); if (EdmLibraryExtensions.IsGeographyType(expectedValueTypeReference)) { spatialValue = jsonObjectFormatter.Read <Microsoft.Spatial.Geography>(jsonObject); } else { spatialValue = jsonObjectFormatter.Read <Microsoft.Spatial.Geometry>(jsonObject); } } if (spatialValue == null) { throw new ODataException(ODataErrorStrings.ODataJsonReaderCoreUtils_CannotReadSpatialPropertyValue); } return(spatialValue); }
public void StartBufferingAndTryToReadInStreamErrorPropertyValue_Works() { // Arrange const string payload = @"{""code"":"""",""message"":"""",""target"":""any target""," + @"""details"":[{""code"":""500"",""target"":""another target"",""message"":""any msg""}]}"; var reader = new StringReader(payload); var jsonReader = new BufferingJsonReader(reader, "any", 0, ODataFormat.Json, false); ODataError error; // Act jsonReader.Read(); var result = jsonReader.StartBufferingAndTryToReadInStreamErrorPropertyValue(out error); // Assert Assert.True(result); Assert.Equal("any target", error.Target); Assert.Equal(1, error.Details.Count); var detail = error.Details.Single(); Assert.Equal("500", detail.ErrorCode); Assert.Equal("another target", detail.Target); Assert.Equal("any msg", detail.Message); }
private static void AdvanceReaderToFirstProperty(BufferingJsonReader bufferingJsonReader) { // Read start and then over the object start. bufferingJsonReader.Read(); bufferingJsonReader.Read(); bufferingJsonReader.NodeType.Should().Be(JsonNodeType.Property); }
/// <summary> /// Tries to read a null value from the JSON reader. /// </summary> /// <param name="jsonReader">The JSON reader to read from.</param> /// <param name="inputContext">The input context with all the settings.</param> /// <param name="expectedTypeReference">The expected type reference of the value.</param> /// <param name="validateNullValue">true to validate null values; otherwise false.</param> /// <param name="propertyName">The name of the property whose value is being read, if applicable (used for error reporting).</param> /// <param name="isDynamicProperty">Indicates whether the property is dynamic or unknown.</param> /// <returns>true if a null value could be read from the JSON reader; otherwise false.</returns> /// <remarks>If the method detects a null value it will read it (position the reader after the null value); /// otherwise the reader does not move.</remarks> internal static bool TryReadNullValue( BufferingJsonReader jsonReader, ODataInputContext inputContext, IEdmTypeReference expectedTypeReference, bool validateNullValue, string propertyName, bool? isDynamicProperty = null) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(inputContext != null, "inputContext != null"); if (jsonReader.NodeType == JsonNodeType.PrimitiveValue && jsonReader.Value == null) { jsonReader.ReadNext(); // NOTE: when reading a null value we will never ask the type resolver (if present) to resolve the // type; we always fall back to the expected type. ReaderValidationUtils.ValidateNullValue( inputContext.Model, expectedTypeReference, inputContext.MessageReaderSettings, validateNullValue, propertyName, isDynamicProperty); return true; } return false; }
internal ODataJsonLightInputContext( ODataFormat format, TextReader reader, ODataMediaType contentType, ODataMessageReaderSettings messageReaderSettings, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageReaderSettings, readingResponse, synchronous, model, urlResolver) { Debug.Assert(reader != null, "reader != null"); Debug.Assert(contentType != null, "contentType != null"); try { ExceptionUtils.CheckArgumentNotNull(format, "format"); ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings"); } catch (ArgumentNullException) { // Dispose the message stream if we failed to create the input context. reader.Dispose(); throw; } try { this.textReader = reader; if (contentType.HasStreamingSetToTrue()) { this.jsonReader = new BufferingJsonReader( this.textReader, JsonLightConstants.ODataErrorPropertyName, messageReaderSettings.MessageQuotas.MaxNestingDepth, ODataFormat.Json, contentType.HasIeee754CompatibleSetToTrue()); } else { // If we have a non-streaming Json Light content type we need to use the re-ordering Json reader this.jsonReader = new ReorderingJsonReader(this.textReader, messageReaderSettings.MessageQuotas.MaxNestingDepth, contentType.HasIeee754CompatibleSetToTrue()); } } catch (Exception e) { // Dispose the message stream if we failed to create the input context. if (ExceptionUtils.IsCatchableExceptionType(e) && reader != null) { reader.Dispose(); } throw; } // dont know how to get MetadataDocumentUri uri here, messageReaderSettings do not have one // Uri metadataDocumentUri = messageReaderSettings..MetadataDocumentUri == null ? null : messageReaderSettings.MetadataDocumentUri.BaseUri; // the uri here is used here to create the FullMetadataLevel can pass null in this.metadataLevel = JsonLight.JsonLightMetadataLevel.Create(contentType, null, model, readingResponse); }
/// <summary> /// Perform the actual cleanup work. /// </summary> /// <param name="disposing">If 'true' this method is called from user code; if 'false' it is called by the runtime.</param> protected override void Dispose(bool disposing) { if (disposing) { try { if (this.textReader != null) { this.textReader.Dispose(); } } finally { this.textReader = null; this.jsonReader = null; } } base.Dispose(disposing); }
private static void AdvanceReaderToFirstPropertyValue(BufferingJsonReader bufferingJsonReader) { AdvanceReaderToFirstProperty(bufferingJsonReader); // Read over property name bufferingJsonReader.Read(); }