public void Deserialize(object obj, IJsonReader jsonReader) { var cd = _types[obj.GetType()]; var data = jsonReader.ReadNext(); while (data != null) { if (data is JsonObjectSimple) { var jsonSimple = data as JsonObjectSimple; if (cd.Attributes.ContainsKey(jsonSimple.Name)) { cd.Attributes[jsonSimple.Name].PropertyFabric.SetValue(obj, jsonSimple.Value); } } if (data is JsonObjectClass) { var jsonObject = data as JsonObjectClass; if (cd.Nodes.ContainsKey(jsonObject.Name)) { DeserializeClassProperty(obj, cd.Nodes[jsonObject.Name], jsonObject.Class); } } if (data is JsonArray) { var jsonArray = data as JsonArray; if (cd.Nodes.ContainsKey(jsonArray.Name)) { var pd = cd.Nodes[jsonArray.Name]; if (pd is PdList) { DeserializeList(obj, (PdList)cd.Nodes[jsonArray.Name], jsonArray.Array); } if (pd is PdDictionary) { DeserializeDict(obj, (PdDictionary)cd.Nodes[jsonArray.Name], jsonArray.Array); } } } data = jsonReader.ReadNext(); } }
private void DeserializeList(object obj, PdList pd, IJsonReader jsonReader) { var list = (IList)pd.PropertyFabric.CreateInstance(obj); var jsonData = jsonReader.ReadNext(); while (jsonData != null) { var item = DeserializeListItem(pd, jsonData); list.Add(item); jsonData = jsonReader.ReadNext(); } }
private void DeserializeDict(object obj, PdDictionary pd, IJsonReader jsonReader) { var dict = (IDictionary)pd.PropertyFabric.CreateInstance(obj); var jsonData = jsonReader.ReadNext(); while (jsonData != null) { var key = pd.KeyFabric.StringToObject(jsonData.Name); var item = DeserializeListItem(pd, jsonData); dict.Add(key, item); jsonData = jsonReader.ReadNext(); } }
/// <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( IJsonReader 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. inputContext.MessageReaderSettings.Validator.ValidateNullValue( expectedTypeReference, validateNullValue, propertyName, isDynamicProperty); return(true); } return(false); }
/// <summary> /// 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>The property name of the property node read.</returns> internal static string ReadPropertyName(this IJsonReader jsonReader) { Debug.Assert(jsonReader != null, "jsonReader != null"); jsonReader.ValidateNodeType(JsonNodeType.Property); string propertyName = jsonReader.GetPropertyName(); jsonReader.ReadNext(); return(propertyName); }
/// <summary> /// 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>an instance of IDictionary containing the spatial value.</returns> private static IDictionary <string, object> ReadObjectValue(IJsonReader 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); IDictionary <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. jsonReader.ReadNext(); } while (jsonReader.NodeType != JsonNodeType.EndObject) { // read the property name string propertyName = jsonReader.ReadPropertyName(); // read the property value object propertyValue = null; switch (jsonReader.NodeType) { case JsonNodeType.PrimitiveValue: propertyValue = jsonReader.ReadPrimitiveValue(); break; case JsonNodeType.StartArray: propertyValue = ReadArrayValue(jsonReader, inputContext, recursionDepth); break; case JsonNodeType.StartObject: propertyValue = ReadObjectValue(jsonReader, /*insideJsonObjectValue*/ false, inputContext, recursionDepth); break; default: Debug.Assert(false, "We should never reach here - There should be matching end element"); return(null); } jsonValue.Add(ODataAnnotationNames.RemoveAnnotationPrefix(propertyName), propertyValue); } jsonReader.ReadEndObject(); return(jsonValue); }
/// <summary> /// Read 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 list of json objects.</returns> private static IEnumerable <object> ReadArrayValue(IJsonReader 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> array = new List <object>(); jsonReader.ReadNext(); while (jsonReader.NodeType != JsonNodeType.EndArray) { switch (jsonReader.NodeType) { case JsonNodeType.PrimitiveValue: array.Add(jsonReader.ReadPrimitiveValue()); break; case JsonNodeType.StartObject: array.Add(ReadObjectValue(jsonReader, /*insideJsonObjectValue*/ false, inputContext, recursionDepth)); break; case JsonNodeType.StartArray: array.Add(ReadArrayValue(jsonReader, inputContext, recursionDepth)); break; default: Debug.Assert(false, "We should never have got here - the valid states in array are primitive value or object"); return(null); } } jsonReader.ReadEndArray(); return(array); }
/// <summary> /// 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> private static void WriteCurrentJsonObject(IJsonReader reader, IJsonWriter jsonWriter) { Stack <JsonNodeType> nodeTypes = new Stack <JsonNodeType>(); do { switch (reader.NodeType) { case JsonNodeType.PrimitiveValue: { if (reader.Value != null) { jsonWriter.WritePrimitiveValue(reader.Value); } else { jsonWriter.WriteValue((string)null); } } break; case JsonNodeType.Property: { jsonWriter.WriteName(reader.Value.ToString()); } break; case JsonNodeType.StartObject: { nodeTypes.Push(reader.NodeType); jsonWriter.StartObjectScope(); } break; case JsonNodeType.StartArray: { nodeTypes.Push(reader.NodeType); jsonWriter.StartArrayScope(); } break; case JsonNodeType.EndObject: { Debug.Assert(nodeTypes.Peek() == JsonNodeType.StartObject); nodeTypes.Pop(); jsonWriter.EndObjectScope(); } break; case JsonNodeType.EndArray: { Debug.Assert(nodeTypes.Peek() == JsonNodeType.StartArray); nodeTypes.Pop(); jsonWriter.EndArrayScope(); } break; default: { throw new ODataException(String.Format( CultureInfo.InvariantCulture, "Unexpected reader.NodeType: {0}.", reader.NodeType)); } } reader.ReadNext(); // This can be EndOfInput, where nodeTypes should be empty. }while (nodeTypes.Count != 0); jsonWriter.Flush(); }