public void StartBufferingAndTryToReadInStreamErrorPropertyValue_Works() { // Arrange const string payload = @"{""code"":"""",""message"":"""",""target"":""any target""," + @"""details"":[{""code"":""500"",""target"":""another target"",""message"":""any msg""}]}"; var stringReader = new StringReader(payload); var innerReader = new JsonReader(stringReader, false); var jsonReader = new BufferingJsonReader(innerReader, "any", 0); 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); }
public async Task ReadInStreamErrorPropertyAsync_SkipsNonSupportedPropertiesInErrorDetails() { // Arrange var payload = "{\"error\":{" + $"\"code\":\"{ErrorCode}\"," + $"\"message\":\"{ErrorMessage}\"," + $"\"target\":\"{ErrorTarget}\"," + $"\"details\":[{{\"code\":\"{ErrorDetailErrorCode}\",\"message\":\"{ErrorDetailErrorMessage}\",\"target\":null,\"foo\":\"bar\"}}]}}}}"; var stringReader = new StringReader(payload); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "error", MaxInnerErrorDepth); // Act var exception = await Assert.ThrowsAsync <ODataErrorException>( () => bufferingReader.ReadAsync()); // Assert var error = exception.Error; Assert.NotNull(error); Assert.Null(error.InnerError); Assert.NotNull(error.Details); var errorDetail = Assert.Single(error.Details); Assert.Equal(ErrorDetailErrorCode, errorDetail.ErrorCode); Assert.Equal(ErrorDetailErrorMessage, errorDetail.Message); Assert.Null(errorDetail.Target); } }
private static void AdvanceReaderToFirstPropertyValue(BufferingJsonReader bufferingJsonReader) { AdvanceReaderToFirstProperty(bufferingJsonReader); // Read over property name bufferingJsonReader.Read(); }
public async Task ReadODataResourceAsync() { // Arrange var payload = "{\"Customer\":{\"Id\":1,\"Name\":\"Sue\"}}"; var stringReader = new StringReader(payload); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "any", MaxInnerErrorDepth); // Act await bufferingReader.ReadAsync(); await bufferingReader.ReadStartObjectAsync(); await bufferingReader.ReadPropertyNameAsync(); var odataValue = await bufferingReader.ReadODataValueAsync(); // Assert var resourceValue = Assert.IsType <ODataResourceValue>(odataValue); Assert.Equal(2, resourceValue.Properties.Count()); var prop1 = resourceValue.Properties.First(); var prop2 = resourceValue.Properties.Last(); Assert.Equal("Id", prop1.Name); Assert.Equal(1, prop1.Value); Assert.Equal("Name", prop2.Name); Assert.Equal("Sue", prop2.Value); } }
/// <summary>Constructor.</summary> /// <param name="format">The format for this input context.</param> /// <param name="reader">The reader to use.</param> /// <param name="contentType">The content type of the message to read.</param> /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param> /// <param name="version">The OData protocol version to be used for reading the payload.</param> /// <param name="readingResponse">true if reading a response message; otherwise false.</param> /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param> /// <param name="model">The model to use.</param> /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param> /// <param name="payloadKindDetectionState">JSON Ligth specific state stored during payload kind detection (or null if no payload kind detection happened).</param> internal ODataJsonLightInputContext( ODataFormat format, TextReader reader, MediaType contentType, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver, ODataJsonLightPayloadKindDetectionState payloadKindDetectionState) : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver) { DebugUtils.CheckNoExternalCallers(); 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, ODataAnnotationNames.ODataError, messageReaderSettings.MessageQuotas.MaxNestingDepth, ODataFormat.Json); } 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); } } catch (Exception e) { // Dispose the message stream if we failed to create the input context. if (ExceptionUtils.IsCatchableExceptionType(e) && reader != null) { reader.Dispose(); } throw; } this.payloadKindDetectionState = payloadKindDetectionState; }
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> /// Peeks and collects a raw annotation value from BufferingJsonReader. /// </summary> /// <param name="jsonReader">The BufferingJsonReader.</param> /// <param name="propertyName">The property name.</param> /// <param name="annotationName">The annotation name.</param> private void PeekAndCollectAnnotationRawJson( BufferingJsonReader jsonReader, string propertyName, string annotationName) { if (jsonReader.IsBuffering) { return; // only need to collect annotation for not-buffering pass reading. } try { jsonReader.StartBuffering(); if (jsonReader.NodeType == JsonNodeType.Property) { jsonReader.Read(); // read over annotation name } StringBuilder builder = new StringBuilder(); jsonReader.SkipValue(builder); string annotationRawJson = builder.ToString(); this.AddPropertyAnnotationRawJson(propertyName, annotationName, annotationRawJson); } finally { jsonReader.StopBuffering(); } }
public async Task ReadInStreamErrorPropertyAsync_SkipsNonSupportedPropertiesInInnerError() { // Arrange var payload = "{\"error\":{" + $"\"code\":\"{ErrorCode}\"," + $"\"message\":\"{ErrorMessage}\"," + $"\"target\":\"{ErrorTarget}\"," + "\"innererror\":{" + $"\"type\":\"{InnerErrorTypeName}\"," + $"\"message\":\"{InnerErrorMessage}\"," + $"\"stacktrace\":\"{InnerErrorStackTrace}\"," + "\"foo\":\"bar\"}}}"; var stringReader = new StringReader(payload); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "error", MaxInnerErrorDepth); // Act var exception = await Assert.ThrowsAsync <ODataErrorException>( () => bufferingReader.ReadAsync()); // Assert var error = exception.Error; Assert.NotNull(error); var innerError = error.InnerError; Assert.NotNull(innerError); Assert.Equal(3, innerError.Properties.Count); Assert.Single(innerError.Properties.Where(d => d.Key.Equals("message"))); Assert.Single(innerError.Properties.Where(d => d.Key.Equals("type"))); Assert.Single(innerError.Properties.Where(d => d.Key.Equals("stacktrace"))); Assert.Empty(innerError.Properties.Where(d => d.Key.Equals("foo"))); } }
private static void AdvanceReaderToFirstProperty(BufferingJsonReader bufferingJsonReader) { // Read start and then over the object start. bufferingJsonReader.Read(); bufferingJsonReader.Read(); Assert.Equal(JsonNodeType.Property, bufferingJsonReader.NodeType); }
internal static void AssertBuffering(this BufferingJsonReader bufferedJsonReader) { DebugUtils.CheckNoExternalCallers(); #if DEBUG Debug.Assert(bufferedJsonReader.IsBuffering, "bufferedJsonReader.IsBuffering"); #endif }
/// <summary> /// Tries to peek and collect a raw annotation value from BufferingJsonReader. /// </summary> /// <param name="jsonReader">The BufferingJsonReader.</param> /// <param name="propertyName">The property name.</param> /// <param name="annotationName">The annotation name.</param> public void TryPeekAndCollectAnnotationRawJson( BufferingJsonReader jsonReader, string propertyName, string annotationName) { if (this.shouldCollectAnnotation) { this.PeekAndCollectAnnotationRawJson(jsonReader, propertyName, annotationName); } }
public async Task ReadInStreamErrorPropertyAsync_DoesNotThrowExceptionForUnintelligibleError(string payload) { // Arrange var stringReader = new StringReader(payload); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "error", MaxInnerErrorDepth); // Act & Assert Assert.True(await bufferingReader.ReadAsync()); } }
/// <summary>Constructor.</summary> /// <param name="textReader">The text reader to use.</param> /// <param name="messageInfo">The context information for the message.</param> /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param> internal ODataJsonLightInputContext( TextReader textReader, ODataMessageInfo messageInfo, ODataMessageReaderSettings messageReaderSettings) : base(ODataFormat.Json, messageInfo, messageReaderSettings) { Debug.Assert(messageInfo.MediaType != null, "messageInfo.MediaType != null"); try { this.textReader = textReader; var innerReader = CreateJsonReader(this.Container, this.textReader, messageInfo.MediaType.HasIeee754CompatibleSetToTrue()); if (messageReaderSettings.ArrayPool != null) { // make sure customer also can use reading setting if without DI. JsonReader jsonReader = innerReader as JsonReader; if (jsonReader != null && jsonReader.ArrayPool == null) { jsonReader.ArrayPool = messageReaderSettings.ArrayPool; } } if (messageInfo.MediaType.HasStreamingSetToTrue()) { this.jsonReader = new BufferingJsonReader( innerReader, JsonLightConstants.ODataErrorPropertyName, messageReaderSettings.MessageQuotas.MaxNestingDepth); } else { // If we have a non-streaming Json Light content type we need to use the re-ordering Json reader this.jsonReader = new ReorderingJsonReader(innerReader, messageReaderSettings.MessageQuotas.MaxNestingDepth); } } catch (Exception e) { // Dispose the message stream if we failed to create the input context. if (ExceptionUtils.IsCatchableExceptionType(e) && this.textReader != null) { this.textReader.Dispose(); } throw; } // don't 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 = JsonLightMetadataLevel.Create(messageInfo.MediaType, null, this.Model, this.ReadingResponse); }
/// <summary> /// Disposes the input context. /// </summary> protected override void DisposeImplementation() { try { if (this.textReader != null) { this.textReader.Dispose(); } } finally { this.textReader = null; this.jsonReader = null; } }
public async Task StartBufferingAndTryToReadInStreamErrorPropertyValueAsync_Works() { // Arrange var payload = "{" + $"\"code\":\"{ErrorCode}\"," + $"\"message\":\"{ErrorMessage}\"," + $"\"target\":\"{ErrorTarget}\"," + "\"innererror\":{" + $"\"type\":\"{InnerErrorTypeName}\"," + $"\"message\":\"{InnerErrorMessage}\"," + $"\"stacktrace\":\"{InnerErrorStackTrace}\"," + $"\"internalexception\":{{}}}}," + $"\"details\":[{{\"code\":\"{ErrorDetailErrorCode}\",\"message\":\"{ErrorDetailErrorMessage}\",\"target\":null}}]}}"; var stringReader = new StringReader(payload); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "other", MaxInnerErrorDepth); // Act var result1 = await bufferingReader.ReadAsync(); var result2 = await bufferingReader.StartBufferingAndTryToReadInStreamErrorPropertyValueAsync(); // Assert Assert.True(result1); Assert.True(result2.Item1); var error = result2.Item2; Assert.NotNull(error); Assert.Equal(ErrorCode, error.ErrorCode); Assert.Equal(ErrorMessage, error.Message); Assert.Equal(ErrorTarget, error.Target); var innerError = error.InnerError; Assert.NotNull(innerError); Assert.Equal(InnerErrorMessage, innerError.Message); Assert.Equal(InnerErrorTypeName, innerError.TypeName); Assert.Equal(InnerErrorStackTrace.Replace("\\\\", "\\"), innerError.StackTrace); Assert.NotNull(innerError.InnerError); Assert.NotNull(error.Details); var errorDetail = Assert.Single(error.Details); Assert.Equal(ErrorDetailErrorCode, errorDetail.ErrorCode); Assert.Equal(ErrorDetailErrorMessage, errorDetail.Message); Assert.Null(errorDetail.Target); } }
public async Task CanStreamAsync_ForReaderNotInBufferingState(string payload, bool expected) { var stringReader = new StringReader(string.Format("{{\"Data\":{0}}}", payload)); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "any", MaxInnerErrorDepth); await bufferingReader.ReadAsync(); await bufferingReader.ReadStartObjectAsync(); await bufferingReader.ReadPropertyNameAsync(); Assert.Equal(expected, await bufferingReader.CanStreamAsync()); } }
internal ODataJsonInputContext(ODataFormat format, TextReader reader, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver) { ExceptionUtils.CheckArgumentNotNull<ODataFormat>(format, "format"); ExceptionUtils.CheckArgumentNotNull<ODataMessageReaderSettings>(messageReaderSettings, "messageReaderSettings"); try { this.textReader = reader; this.jsonReader = new BufferingJsonReader(this.textReader, base.UseServerFormatBehavior, messageReaderSettings.MessageQuotas.MaxNestingDepth); } catch (Exception exception) { if (ExceptionUtils.IsCatchableExceptionType(exception) && (reader != null)) { reader.Dispose(); } throw; } }
public async Task ReadInStreamErrorPropertyAsync_ThrowsExceptionForODataErrorRead() { // Arrange var payload = "{\"error\":{" + $"\"code\":\"{ErrorCode}\"," + $"\"message\":\"{ErrorMessage}\"," + $"\"target\":\"{ErrorTarget}\"," + "\"innererror\":{" + $"\"type\":\"{InnerErrorTypeName}\"," + $"\"message\":\"{InnerErrorMessage}\"," + $"\"stacktrace\":\"{InnerErrorStackTrace}\"," + $"\"internalexception\":{{}}}}," + $"\"details\":[{{\"code\":\"{ErrorDetailErrorCode}\",\"message\":\"{ErrorDetailErrorMessage}\",\"target\":null}}]}}}}"; var stringReader = new StringReader(payload); using (var jsonReader = new JsonReader(stringReader, false)) { var bufferingReader = new BufferingJsonReader(jsonReader, "error", MaxInnerErrorDepth); // Act var exception = await Assert.ThrowsAsync <ODataErrorException>( () => bufferingReader.ReadAsync()); // Assert var error = exception.Error; Assert.NotNull(error); Assert.Equal(ErrorCode, error.ErrorCode); Assert.Equal(ErrorMessage, error.Message); Assert.Equal(ErrorTarget, error.Target); var innerError = error.InnerError; Assert.NotNull(innerError); Assert.Equal(InnerErrorMessage, innerError.Message); Assert.Equal(InnerErrorTypeName, innerError.TypeName); Assert.Equal(InnerErrorStackTrace.Replace("\\\\", "\\"), innerError.StackTrace); Assert.NotNull(innerError.InnerError); Assert.NotNull(error.Details); var errorDetail = Assert.Single(error.Details); Assert.Equal(ErrorDetailErrorCode, errorDetail.ErrorCode); Assert.Equal(ErrorDetailErrorMessage, errorDetail.Message); Assert.Null(errorDetail.Target); } }
/// <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); }
/// <summary>Constructor.</summary> /// <param name="format">The format for this input context.</param> /// <param name="reader">The reader to read data from.</param> /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param> /// <param name="version">The OData protocol version to be used for reading the payload.</param> /// <param name="readingResponse">true if reading a response message; otherwise false.</param> /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param> /// <param name="model">The model to use.</param> /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param> internal ODataVerboseJsonInputContext( ODataFormat format, TextReader reader, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(reader != null, "reader != null"); try { ExceptionUtils.CheckArgumentNotNull(format, "format"); ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings"); this.textReader = reader; if (this.UseServerFormatBehavior) { this.jsonReader = new PropertyDeduplicatingJsonReader(this.textReader, messageReaderSettings.MessageQuotas.MaxNestingDepth); } else { this.jsonReader = new BufferingJsonReader(this.textReader, JsonConstants.ODataErrorName, messageReaderSettings.MessageQuotas.MaxNestingDepth, ODataFormat.VerboseJson); } } catch (Exception e) { // Dispose the message stream if we failed to create the input context. if (ExceptionUtils.IsCatchableExceptionType(e) && reader != null) { reader.Dispose(); } throw; } }
internal static void AssertBuffering(this BufferingJsonReader bufferedJsonReader) { #if DEBUG Debug.Assert(bufferedJsonReader.IsBuffering, "bufferedJsonReader.IsBuffering"); #endif }
protected override void DisposeImplementation() { try { if (this.textReader != null) { this.textReader.Dispose(); } } finally { this.textReader = null; this.jsonReader = null; } }
internal ODataJsonLightInputContext( ODataFormat format, TextReader reader, MediaType contentType, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver, ODataJsonLightPayloadKindDetectionState payloadKindDetectionState) : base(format, messageReaderSettings, version, 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; } this.payloadKindDetectionState = payloadKindDetectionState; // 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); }