internal static async Task <bool> TryReadNullValueAsync( #endif IJsonReaderAsync 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 && await jsonReader.GetValueAsync().ConfigureAwait(false) == null) { await jsonReader.ReadNextAsync() .ConfigureAwait(false); // 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. inputContext.MessageReaderSettings.Validator.ValidateNullValue( expectedTypeReference, validateNullValue, propertyName, isDynamicProperty); return(true); } return(false); }
/// <summary> /// Asynchronously reads the next node from the <paramref name="jsonReader"/>, verifies that it is a Property node and returns the property name. /// </summary> /// <param name="jsonReader">The <see cref="JsonReader"/> to read from.</param> /// <returns>A task that represents the asynchronous read operation. /// The value of the TResult parameter contains the property name of the property node read.</returns> internal static async Task <string> ReadPropertyNameAsync(this IJsonReaderAsync jsonReader) { Debug.Assert(jsonReader != null, "jsonReader != null"); jsonReader.ValidateNodeType(JsonNodeType.Property); string propertyName = await jsonReader.GetPropertyNameAsync() .ConfigureAwait(false); await jsonReader.ReadNextAsync() .ConfigureAwait(false); return(propertyName); }
/// <summary> /// Asynchronously reads the json array from the reader. /// </summary> /// <param name="jsonReader">JsonReader instance.</param> /// <param name="inputContext">The input context with all the settings.</param> /// <param name="recursionDepth">The recursion depth to start with.</param> /// <returns>A task that represents the asynchronous read operation. /// The value of the TResult parameter contains a lit of JSON objects.</returns> /// <returns>a list of json objects.</returns> private static async Task <List <object> > ReadArrayValueAsync(IJsonReaderAsync jsonReader, ODataInputContext inputContext, int recursionDepth) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(jsonReader.NodeType == JsonNodeType.StartArray, "jsonReader.NodeType == JsonNodeType.StartArray"); Debug.Assert(inputContext != null, "inputContext != null"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, inputContext.MessageReaderSettings.MessageQuotas.MaxNestingDepth); List <object> items = new List <object>(); await jsonReader.ReadNextAsync() .ConfigureAwait(false); while (jsonReader.NodeType != JsonNodeType.EndArray) { switch (jsonReader.NodeType) { case JsonNodeType.PrimitiveValue: items.Add(await jsonReader.ReadPrimitiveValueAsync() .ConfigureAwait(false)); break; case JsonNodeType.StartObject: items.Add(await ReadObjectValueAsync(jsonReader, /*insideJsonObjectValue*/ false, inputContext, recursionDepth) .ConfigureAwait(false)); break; case JsonNodeType.StartArray: items.Add(await ReadArrayValueAsync(jsonReader, inputContext, recursionDepth) .ConfigureAwait(false)); break; default: Debug.Assert(false, "We should never have got here - the valid states in array are primitive value or object"); return(null); } } await jsonReader.ReadEndArrayAsync() .ConfigureAwait(false); return(items); }
/// <summary> /// Asynchronously writes the current Json object. /// </summary> /// <param name="reader">The Json reader providing the data.</param> /// <param name="jsonWriter">The Json writer writes data into memory stream.</param> /// <returns>A task that represents the asynchronous write operation.</returns> private static async Task WriteCurrentJsonObjectAsync(IJsonReaderAsync reader, IJsonWriterAsync jsonWriter) { Stack <JsonNodeType> nodeTypes = new Stack <JsonNodeType>(); do { switch (reader.NodeType) { case JsonNodeType.PrimitiveValue: object primitiveValue; if ((primitiveValue = await reader.GetValueAsync().ConfigureAwait(false)) != null) { await jsonWriter.WritePrimitiveValueAsync(primitiveValue) .ConfigureAwait(false); } else { await jsonWriter.WriteValueAsync((string)null) .ConfigureAwait(false); } break; case JsonNodeType.Property: object propertyName = await reader.GetValueAsync() .ConfigureAwait(false); await jsonWriter.WriteNameAsync(propertyName.ToString()) .ConfigureAwait(false); break; case JsonNodeType.StartObject: nodeTypes.Push(reader.NodeType); await jsonWriter.StartObjectScopeAsync() .ConfigureAwait(false); break; case JsonNodeType.StartArray: nodeTypes.Push(reader.NodeType); await jsonWriter.StartArrayScopeAsync() .ConfigureAwait(false); break; case JsonNodeType.EndObject: Debug.Assert(nodeTypes.Peek() == JsonNodeType.StartObject); nodeTypes.Pop(); await jsonWriter.EndObjectScopeAsync() .ConfigureAwait(false); break; case JsonNodeType.EndArray: Debug.Assert(nodeTypes.Peek() == JsonNodeType.StartArray); nodeTypes.Pop(); await jsonWriter.EndArrayScopeAsync() .ConfigureAwait(false); break; default: throw new ODataException(Strings.ODataJsonLightBatchBodyContentReaderStream_UnexpectedNodeType(reader.NodeType)); } await reader.ReadNextAsync() .ConfigureAwait(false); // This can be EndOfInput, where nodeTypes should be empty. }while (nodeTypes.Count != 0); await jsonWriter.FlushAsync() .ConfigureAwait(false); }
/// <summary> /// Asynchronously reads the json object value from the jsonReader /// </summary> /// <param name="jsonReader">Json reader to read payload from the wire.</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="recursionDepth">The recursion depth to start with.</param> /// <returns>A task that represents the asynchronous read operation. /// The value of the TResult parameter contains an instance of IDictionary containing the spatial value.</returns> private static async Task <Dictionary <string, object> > ReadObjectValueAsync( IJsonReaderAsync jsonReader, bool insideJsonObjectValue, ODataInputContext inputContext, int recursionDepth) { Debug.Assert(jsonReader != null, "jsonReader != null"); Debug.Assert(insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.StartObject, "insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.StartObject"); Debug.Assert( !insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.Property || jsonReader.NodeType == JsonNodeType.EndObject, "!insideJsonObjectValue || jsonReader.NodeType == JsonNodeType.Property || jsonReader.NodeType == JsonNodeType.EndObject"); Debug.Assert(inputContext != null, "inputContext != null"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, inputContext.MessageReaderSettings.MessageQuotas.MaxNestingDepth); Dictionary <string, object> jsonValue = new Dictionary <string, object>(StringComparer.Ordinal); if (!insideJsonObjectValue) { // Note that if the insideJsonObjectValue is true we will ignore the odata.type instance annotation // which might have been there. This is OK since for spatial we only need the normal properties anyway. await jsonReader.ReadNextAsync() .ConfigureAwait(false); } while (jsonReader.NodeType != JsonNodeType.EndObject) { // read the property name string propertyName = await jsonReader.ReadPropertyNameAsync() .ConfigureAwait(false); // read the property value object propertyValue; switch (jsonReader.NodeType) { case JsonNodeType.PrimitiveValue: propertyValue = await jsonReader.ReadPrimitiveValueAsync() .ConfigureAwait(false); break; case JsonNodeType.StartArray: propertyValue = await ReadArrayValueAsync(jsonReader, inputContext, recursionDepth) .ConfigureAwait(false); break; case JsonNodeType.StartObject: propertyValue = await ReadObjectValueAsync(jsonReader, /*insideJsonObjectValue*/ false, inputContext, recursionDepth) .ConfigureAwait(false); break; default: Debug.Assert(false, "We should never reach here - There should be matching end element"); return(null); } jsonValue.Add(ODataAnnotationNames.RemoveAnnotationPrefix(propertyName), propertyValue); } await jsonReader.ReadEndObjectAsync() .ConfigureAwait(false); return(jsonValue); }