private object ReadExpandoObject(JsonReader reader, JsonSerializer serializer) { IDictionary <string, object> expandoObject = new ExpandoObject(); while (reader.Read()) { switch (reader.TokenType) { case JsonToken.PropertyName: string propertyName = reader.Value.ToString(); if (!reader.Read()) { throw JsonSerializationExceptionHelper.Create(reader, "Unexpected end when reading ExpandoObject."); } object v = ReadValue(reader, serializer); expandoObject[propertyName] = v; break; case JsonToken.Comment: break; case JsonToken.EndObject: return(expandoObject); } } throw JsonSerializationExceptionHelper.Create(reader, "Unexpected end when reading ExpandoObject."); }
public static void ReadAndAssert(this JsonReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } if (!reader.Read()) { throw JsonSerializationExceptionHelper.Create(reader, "Unexpected end when reading JSON."); } }
private static Type GetColumnDataType(JsonReader reader, out bool isAmbiguous) { JsonToken tokenType = reader.TokenType; switch (tokenType) { case JsonToken.Integer: case JsonToken.Boolean: case JsonToken.Float: case JsonToken.String: case JsonToken.Date: case JsonToken.Bytes: isAmbiguous = false; return(reader.ValueType); case JsonToken.Null: case JsonToken.Undefined: isAmbiguous = true; return(typeof(string)); case JsonToken.StartArray: reader.ReadAndAssert(); if (reader.TokenType == JsonToken.StartObject) { isAmbiguous = false; return(typeof(DataTable)); // nested datatable } else { isAmbiguous = false; bool innerAmbiguous; // Handling ambiguity in array entries is not yet implemented because the first non-ambiguous entry in the array // might occur anywhere in the sequence, requiring us to scan the entire array to determine the type, // e.g., given: [null, null, null, 314, null] // we would need to scan until the 314 value, and do: // return typeof(Nullable<>).MakeGenericType(new[] { reader.ValueType }).MakeArrayType(); Type arrayType = GetColumnDataType(reader, out innerAmbiguous); return(arrayType.MakeArrayType()); } default: throw JsonSerializationExceptionHelper.Create(reader, "Unexpected JSON token when reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType)); } }
// Adapted from https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/DataTableConverter.cs // Original license: https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md /// <summary> /// Reads the JSON representation of the object. /// </summary> /// <param name="reader">The <see cref="JsonReader"/> to read from.</param> /// <param name="objectType">Type of the object.</param> /// <param name="existingValue">The existing value of object being read.</param> /// <param name="serializer">The calling serializer.</param> /// <returns>The object value.</returns> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } DataTable dt = existingValue as DataTable; if (dt == null) { // handle typed datasets dt = (objectType == typeof(DataTable)) ? new DataTable() : (DataTable)Activator.CreateInstance(objectType); } // DataTable is inside a DataSet // populate the name from the property name if (reader.TokenType == JsonToken.PropertyName) { dt.TableName = (string)reader.Value; reader.ReadAndAssert(); if (reader.TokenType == JsonToken.Null) { return(dt); } } if (reader.TokenType != JsonToken.StartArray) { throw JsonSerializationExceptionHelper.Create(reader, "Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); } reader.ReadAndAssert(); var ambiguousColumnTypes = new HashSet <string>(); while (reader.TokenType != JsonToken.EndArray) { CreateRow(reader, dt, serializer, ambiguousColumnTypes); reader.ReadAndAssert(); } return(dt); }
private object ReadList(JsonReader reader, JsonSerializer serializer) { IList <object> list = new List <object>(); while (reader.Read()) { switch (reader.TokenType) { case JsonToken.Comment: break; default: object v = ReadValue(reader, serializer); list.Add(v); break; case JsonToken.EndArray: return(list); } } throw JsonSerializationExceptionHelper.Create(reader, "Unexpected end when reading ExpandoObject."); }
private object ReadValue(JsonReader reader, JsonSerializer serializer) { if (!reader.MoveToContent()) { throw JsonSerializationExceptionHelper.Create(reader, "Unexpected end when reading ExpandoObject."); } switch (reader.TokenType) { case JsonToken.StartObject: return(ReadObject(reader, serializer)); case JsonToken.StartArray: return(ReadList(reader, serializer)); default: if (JsonTokenUtils.IsPrimitiveToken(reader.TokenType)) { return(reader.Value); } throw JsonSerializationExceptionHelper.Create(reader, string.Format("Unexpected token when converting ExpandoObject: {0}", reader.TokenType)); } }