/// <summary/> private static IEnumerable<KeyValuePair<string,T>> ApplyPath<T>(JToken root, string path) { // Children var children = SelectChildren<T>(root, path); foreach(var token in children) { // Token => T var value = (T)JsonFunctions.ConvertToken(token, typeof(T)); // Tuple(path, value) yield return new KeyValuePair<string,T>(token.Path, value); } }
/// <summary/> internal static object ConvertToken(JToken token, Type type) { try { if(type == typeof(string)) { return JsonFunctions.GetTokenString(token); } // We simply delegate to Json.Net for data conversions return token.ToObject(type); } catch(Exception e) { // Make this easier to debug (with field and type context) // Note: We don't expose the actual value to be converted in the error message (since it might be sensitive, information disclosure) throw new JsonSerializationException( string.Format(typeof(JsonToken).Namespace + " failed to deserialize '{0}' from '{1}' to '{2}'", token.Path, token.Type.ToString(), type.FullName), e); } }
protected override void JObjectToRow(JObject o, IUpdatableRow row) { if (jsonPaths.Length == 0) { base.JObjectToRow(o, row); } else { for (int i = 0; i < jsonPaths.Length; i++) { var path = jsonPaths[i]; var jObj = findByPath(o, path); object value = null; if (jObj != default(JToken)) { var schemaColumn = row.Schema[i]; value = JsonFunctions.ConvertToken(jObj, schemaColumn.Type) ?? schemaColumn.DefaultValue; } row.Set <object>(i, value); } } }
/// <summary/> protected virtual void JObjectToRow(JObject o, IUpdatableRow row) { foreach (var c in row.Schema) { JToken token = null; object value = c.DefaultValue; // All fields are represented as columns // Note: Each JSON row/payload can contain more or less columns than those specified in the row schema // We simply update the row for any column that matches (and in any order). if (o.TryGetValue(c.Name, out token) && token != null) { // Note: We simply delegate to Json.Net for all data conversions // For data conversions beyond what Json.Net supports, do an explicit projection: // ie: SELECT DateTime.Parse(datetime) AS datetime, ... // Note: Json.Net incorrectly returns null even for some non-nullable types (sbyte) // We have to correct this by using the default(T) so it can fit into a row value value = JsonFunctions.ConvertToken(token, c.Type) ?? c.DefaultValue; } // Update row.Set <object>(c.Name, value); } }
/// <summary/> internal static object ConvertToken(JToken token, Type type) { try { if (type == typeof(string)) { return(JsonFunctions.GetTokenString(token)); } if (type == typeof(byte[])) { var bytes = Encoding.UTF8.GetBytes(JsonFunctions.GetTokenString(token)); using (var msi = new MemoryStream(bytes)) using (var mso = new MemoryStream()) { using (var gs = new GZipStream(mso, CompressionLevel.Optimal)) { msi.CopyTo(gs); } return(mso.ToArray()); }; } // We simply delegate to Json.Net for data conversions return(token.ToObject(type)); } catch (Exception e) { // Make this easier to debug (with field and type context) // Note: We don't expose the actual value to be converted in the error message (since it might be sensitive, information disclosure) throw new JsonSerializationException( string.Format(typeof(JsonToken).Namespace + " failed to deserialize '{0}' from '{1}' to '{2}'", token.Path, token.Type.ToString(), type.FullName), e); } }