/// <summary> /// Converts JSONMap into supplied row instance. /// The extra data found in JSON map will be placed in AmorphousData dictionary if the row implements IAmorphousData, discarded otherwise. /// Note: This method provides "the best match" and does not guarantee that all data will/can be converted from JSON, i.e. /// it can only convert one dimensional arrays and Lists of either primitive or TypeRow-derived entries /// </summary> /// <param name="doc">Data document instance to convert into</param> /// <param name="jsonMap">JSON data to convert into row</param> /// <param name="fromUI">When true indicates that data came from UI, hence NonUI-marked fields should be skipped. True by default</param> /// <param name="options">Used for backend name matching or null (any target)</param> public static void ToDoc(Doc doc, JsonDataMap jsonMap, bool fromUI = true, DocReadOptions?options = null) { if (doc == null || jsonMap == null) { throw new JSONDeserializationException(StringConsts.ARGUMENT_ERROR + "JSONReader.ToDoc(doc|jsonMap=null)"); } var field = ""; try { var tDoc = doc.GetType(); var customHandler = JsonHandlerAttribute.TryFind(tDoc); if (customHandler != null) { var castResult = customHandler.TypeCastOnRead(jsonMap, tDoc, fromUI, options ?? DocReadOptions.BindByCode); //only reacts to ChangeSource because this method works on pre-allocated doc if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.ChangedSourceValue) { jsonMap = (castResult.Value as JsonDataMap).NonNull("Changed source value must be of JsonDataMap type for root data documents"); } } toDoc(doc, options.HasValue ? options.Value : DocReadOptions.BindByCode, jsonMap, ref field, fromUI); } catch (Exception error) { throw new JSONDeserializationException("JSONReader.ToDoc(doc, jsonMap) error in '{0}': {1}".Args(field, error.ToMessageWithType()), error); } }
private static TypedDoc toTypedDoc(Type type, DocReadOptions?options, JsonDataMap jsonMap, ref string field, bool fromUI) { var toAllocate = type; var customHandler = JsonHandlerAttribute.TryFind(type); if (customHandler != null) { var castResult = customHandler.TypeCastOnRead(jsonMap, type, fromUI, options ?? DocReadOptions.BindByCode); if (castResult.Outcome >= JsonHandlerAttribute.TypeCastOutcome.ChangedTargetType) { toAllocate = castResult.ToType.IsOfType(type, "Changed type must be a subtype of specific document type"); } if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.ChangedSourceValue) { jsonMap = (castResult.Value as JsonDataMap).NonNull("Changed source value must be of JsonDataMap type for root data documents"); } else if (castResult.Outcome == JsonHandlerAttribute.TypeCastOutcome.HandledCast) { return(castResult.Value.ValueIsOfType(type, "HandledCast must return TypedDoc for root data documents") as TypedDoc); } } if (toAllocate.IsAbstract) { throw new JSONDeserializationException(StringConsts.JSON_DESERIALIZATION_ABSTRACT_TYPE_ERROR.Args(toAllocate.Name, nameof(JsonHandlerAttribute))); } var doc = (TypedDoc)SerializationUtils.MakeNewObjectInstance(toAllocate); toDoc(doc, options.HasValue ? options.Value : DocReadOptions.BindByCode, jsonMap, ref field, fromUI); return(doc); }
/// <summary> /// If there is error, converts its details to JSONDataMap /// </summary> public static Azos.Serialization.JSON.JsonDataMap ToJSONDataMap(this Exception error, bool recurse = true, bool stackTrace = false) { if (error == null) { return(null); } var result = new Azos.Serialization.JSON.JsonDataMap(false); result["Type"] = error.GetType().FullName; result["Msg"] = error.Message; result["Data"] = error.Data; result["Src"] = error.Source; if (stackTrace) { result["STrace"] = error.StackTrace; } if (recurse) { result["Inner"] = error.InnerException.ToJSONDataMap(recurse); } else { result["Inner.Type"] = error.InnerException != null?error.InnerException.GetType().FullName : null; result["Inner.Msg"] = error.InnerException != null ? error.InnerException.Message : null; if (stackTrace) { result["Inner.STrace"] = error.InnerException != null ? error.InnerException.StackTrace : null; } } return(result); }
private static TypedDoc toTypedDoc(Type type, NameBinding?nameBinding, JsonDataMap jsonMap, ref string field, bool fromUI) { var doc = (TypedDoc)SerializationUtils.MakeNewObjectInstance(type); toDoc(doc, nameBinding.HasValue ? nameBinding.Value : NameBinding.ByCode, jsonMap, ref field, fromUI); return(doc); }
private void buildNode(ConfigSectionNode node, JsonDataMap map) { foreach (var kvp in map) { var cmap = kvp.Value as JsonDataMap; if (cmap != null) { buildNode(node.AddChildNode(kvp.Key), cmap); } else { node.AddAttributeNode(kvp.Key, kvp.Value); } } }
/// <summary> /// Converts JSONMap into typed data document of the requested type. /// The requested type must be derived from Azos.Data.TypedDoc. /// The extra data found in JSON map will be placed in AmorphousData dictionary if the row implements IAmorphousData, discarded otherwise. /// Note: This method provides "the best match" and does not guarantee that all data will/can be converted from JSON, i.e. /// it can only convert one dimensional arrays and Lists of either primitive or TypeRow-derived entries /// </summary> /// <param name="type">TypedDoc subtype to convert into</param> /// <param name="jsonMap">JSON data to convert into data doc</param> /// <param name="fromUI">When true indicates that data came from UI, hence NonUI-marked fields should be skipped. True by default</param> /// <param name="options">Used for backend name matching or null (any target)</param> public static TypedDoc ToDoc(Type type, JsonDataMap jsonMap, bool fromUI = true, DocReadOptions?options = null) { if (!typeof(TypedDoc).IsAssignableFrom(type) || jsonMap == null) { throw new JSONDeserializationException(StringConsts.ARGUMENT_ERROR + "JSONReader.ToDoc(type|jsonMap=null)"); } var field = ""; try { return(toTypedDoc(type, options, jsonMap, ref field, fromUI)); } catch (Exception error) { throw new JSONDeserializationException("JSONReader.ToDoc(jsonMap) error in '{0}': {1}".Args(field, error.ToMessageWithType()), error); } }
/// <summary> /// Turns URL encoded content into JSONDataMap /// </summary> public static JsonDataMap FromURLEncodedString(string content, bool caseSensitive = false) { var result = new JsonDataMap(caseSensitive); if (content.IsNullOrWhiteSpace()) { return(result); } int queryLen = content.Length; int idx = 0; while (idx < queryLen) { int ampIdx = content.IndexOf('&', idx); int kvLen = (ampIdx != -1) ? ampIdx - idx : queryLen - idx; if (kvLen < 1) { idx = ampIdx + 1; continue; } int eqIdx = content.IndexOf('=', idx, kvLen); if (eqIdx == -1) { var key = Uri.UnescapeDataString(content.Substring(idx, kvLen).Replace('+', ' ')); result.Add(key, null); } else { int keyLen = eqIdx - idx; if (keyLen > 0) { var key = Uri.UnescapeDataString(content.Substring(idx, keyLen).Replace('+', ' ')); var val = Uri.UnescapeDataString(content.Substring(eqIdx + 1, kvLen - keyLen - 1).Replace('+', ' ')); result.Add(key, val); } } idx += kvLen + 1; } return(result); }
/// <summary> /// Converts JSONMap into supplied row instance. /// The extra data found in JSON map will be placed in AmorphousData dictionary if the row implements IAmorphousData, discarded otherwise. /// Note: This method provides "the best match" and does not guarantee that all data will/can be converted from JSON, i.e. /// it can only convert one dimensional arrays and Lists of either primitive or TypeRow-derived entries /// </summary> /// <param name="doc">Data document instance to convert into</param> /// <param name="jsonMap">JSON data to convert into row</param> /// <param name="fromUI">When true indicates that data came from UI, hence NonUI-marked fields should be skipped. True by default</param> /// <param name="nameBinding">Used for backend name matching or null (any target)</param> public static void ToDoc(Doc doc, JsonDataMap jsonMap, bool fromUI = true, NameBinding?nameBinding = null) { if (doc == null || jsonMap == null) { throw new JSONDeserializationException(StringConsts.ARGUMENT_ERROR + "JSONReader.ToDoc(doc|jsonMap=null)"); } var field = ""; try { toDoc(doc, nameBinding.HasValue ? nameBinding.Value : NameBinding.ByCode, jsonMap, ref field, fromUI); } catch (Exception error) { throw new JSONDeserializationException("JSONReader.ToDoc(doc, jsonMap) error in '{0}': {1}".Args(field, error.ToMessageWithType()), error); } }
private static IJsonDataObject deserializeObject(object root) { if (root == null) { return(null); } var data = root as IJsonDataObject; if (data == null) { data = new JsonDataMap { { "value", root } } } ; return(data); }
/// <summary> /// Appends contents of another JSONDataMap for keys that do not exist in this one or null. /// Only appends references, does not provide deep reference copy /// </summary> public JsonDataMap Append(JsonDataMap other, bool deep = false) { if (other == null) { return(this); } foreach (var kvp in other) { var here = this[kvp.Key]; if (here == null) { this[kvp.Key] = kvp.Value; } else if (deep && here is JsonDataMap) { ((JsonDataMap)here).Append(kvp.Value as JsonDataMap, deep); } } return(this); }
private static void toDoc(Doc doc, DocReadOptions options, JsonDataMap jsonMap, ref string field, bool fromUI) { var amorph = doc as IAmorphousData; var schema = doc.Schema; foreach (var mfld in jsonMap) { field = mfld.Key; var fv = mfld.Value; //Multi-targeting for deserialization to TypedDoc from JSON Schema.FieldDef def; if (options.BindBy == DocReadOptions.By.CodeName) { def = schema[field]; } else { def = schema.TryFindFieldByTargetedBackendName(options.TargetName, field);//what about case sensitive json name? } //No such field exists in a typed doc, try to put in amorphous data if (def == null) { if (amorph != null) { if (amorph.AmorphousDataEnabled) { amorph.AmorphousData[mfld.Key] = fv; } } continue; } if (fromUI && def.NonUI) { continue; //skip NonUI fields } //weed out NULLS here if (fv == null) { doc.SetFieldValue(def, null); continue; } //fv is NEVER NULL here var wasset = setOneField(doc, def, fv, fromUI, options); //<------------------- field assignment //try to put in amorphous data if could not be set in a field if (!wasset && amorph != null) { if (amorph.AmorphousDataEnabled) { amorph.AmorphousData[mfld.Key] = fv; } } }//foreach field in jsonMap //process FORM var form = doc as Form; if (form != null) { form.FormMode = jsonMap[Form.JSON_MODE_PROPERTY].AsEnum <FormMode>(FormMode.Unspecified); form.CSRFToken = jsonMap[Form.JSON_CSRF_PROPERTY].AsString(); var roundtrip = jsonMap[Form.JSON_ROUNDTRIP_PROPERTY].AsString(); if (roundtrip.IsNotNullOrWhiteSpace()) { form.SetRoundtripBagFromJSONString(roundtrip); } } if (amorph != null && amorph.AmorphousDataEnabled) { amorph.AfterLoad(options.TargetName ?? "json"); } }
/// <summary> /// Generic version of ToDoc(Type...)/> /// </summary> /// <typeparam name="T">TypedDoc</typeparam> public static T ToDoc <T>(JsonDataMap jsonMap, bool fromUI = true, DocReadOptions?options = null) where T : TypedDoc { return(ToDoc(typeof(T), jsonMap, fromUI, options) as T); }
/// <summary> /// Deserializes into Rowset or Table from JSONDataMap, as serialized by RowsedBase.WriteAsJSON() /// </summary> public static RowsetBase ToRowset(JsonDataMap jsonMap, bool schemaOnly = false, bool readOnlySchema = false) { return(RowsetBase.FromJSON(jsonMap, schemaOnly, readOnlySchema)); }
/// <summary> /// Generic version of ToDoc(Type, JSONDataMap, bool)/> /// </summary> /// <typeparam name="T">TypedDoc</typeparam> public static T ToDoc <T>(JsonDataMap jsonMap, bool fromUI = true, NameBinding?nameBinding = null) where T : TypedDoc { return(ToDoc(typeof(T), jsonMap, fromUI, nameBinding) as T); }