public static async Task <IJsonType> DeserializeObject(string json, bool ignoreErrors = false) { var javaScriptObject = Interop.ExecuteJavaScript("JSON.parse($0)", json); IJsonType cSharpNestedDictionariesAndLists = await ConvertJavaScriptObjectToCSharpNestedDictionariesAndLists(javaScriptObject, ignoreErrors); return(cSharpNestedDictionariesAndLists); }
/// <summary> /// Parses the json tree recursive. /// </summary> /// <param name="parent">The parent.</param> /// <param name="treeJson">The tree json.</param> private void ParseJsonTreeRecursive(ASTreeViewNode parent, JsonArray treeJson) { for (int i = 0; i < treeJson.Count; i++) { IJsonType type = treeJson[i]; if (type is JsonObject) { JsonObject joTreeNode = (JsonObject)type; ASTreeViewNode curNode = ParseJsonToNode(joTreeNode); if (i + 1 < treeJson.Count) { //test next item IJsonType nextType = treeJson[i + 1]; if (nextType is JsonArray) { //has children ParseJsonTreeRecursive(curNode, (JsonArray)nextType); //skip next i++; } } parent.AppendChild(curNode); } } }
/// <summary> /// Maps the specified value to the type of the type paramater. /// </summary> /// <typeparam name="T">The type to map to.</typeparam> /// <param name="value">The value to map.</param> /// <returns>The mapped value if not logically null, otherwise the default value of /// <typeparamref name="T"/>.</returns> public static T Map <T>(IJsonType value) where T : IJsonType { if (value == null || value.JsonTypeCode == JsonTypeCode.Null) { return(default(T)); } return((T)value); }
/// <summary> /// 转成字符串 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string JsonObjectToString(IJsonType obj) { if (obj == null) { return(string.Empty); } return(obj.ToString()); }
/// <summary> /// 转成Decimal /// </summary> /// <param name="obj"></param> /// <returns></returns> public static Decimal JsonObjectToDecimal(IJsonType obj) { if (obj is JsonNull || obj.ToString() == "") { return(0); } return(Convert.ToDecimal(obj.ToString())); }
/// <summary> /// 转成整型 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static int JsonObjectToInt(IJsonType obj) { if (obj is JsonNull || obj.ToString() == "") { return(0); } return(Convert.ToInt32(obj.ToString().Split('.')[0])); }
/// <summary> /// 转成长整型 /// </summary> public static long JsonObjectToLong(IJsonType obj) { if (obj == null || obj is JsonNull || obj.ToString() == "") { return(0); } return(Convert.ToInt64(obj.ToString().Split('.')[0])); }
/// <summary> /// 转成字符串 /// </summary> public static DateTime JsonObjectToDateTime(IJsonType obj) { if (obj == null || obj is JsonNull) { return(DateTime.MinValue); } return(Convert.ToDateTime(obj.ToString())); }
private async void Button_Click_DynamicDeserialization(object sender, RoutedEventArgs e) { if (!string.IsNullOrEmpty(_json)) { IJsonType deserializedObject = await JsonConvert.DeserializeObject(_json); MessageBox.Show("Product name: " + deserializedObject["Name"].Value.ToString()); MessageBox.Show("Name of the second feature: " + deserializedObject["Features"][1]["Name"].Value.ToString()); MessageBox.Show("Name of the third available size: " + deserializedObject["Sizes"][2].Value.ToString()); // Expected Result: "Product name: TestProduct" // Expected Result: "Name of the second feature: TestFeature2" // Expected Result: "Name of the third available size: Large" } else { MessageBox.Show("Please click on the Serialize button first."); } }
/// <summary> /// parse a JsonArray (array of items) or JsonObject (single game/item) /// </summary> protected GardenItem ParseJson(IJsonType j, Vector2 posOffset) { if (j is JsonArray) { JsonArray ja = j as JsonArray; Vector2 childPosOffset = posOffset; Vector2 posPrevious = Vector2.Zero; //Vector2 childPosPrevious = Vector2.Zero; Vector2 sectionWidthHeight = new Vector2(999f, 999f); GardenItem gi = null; foreach (IJsonType jChild in ja) { // parse each subitem and add to gamelist gi = ParseJson(jChild, childPosOffset); if (gi == null) { continue; } // optional first SectionID item of a JsonArray may contain position offset info for all items if (gi.IsSectionId) { childPosOffset += gi.Position; // WARNING mis-use the posdelta field for section width/height!! sectionWidthHeight = gi.PositionDelta; //childPosPrevious = Vector2.Zero; posPrevious = Vector2.Zero - Vector2.UnitX; // for first item of a section, apply a shift to align item to (0,0) continue; } // calculate correct item position if (!gi.IsPositionGiven) { gi.Position = posPrevious; do { if (gi.IsPositionDeltaGiven) { gi.Position += gi.PositionDelta; } else { gi.Position += Vector2.UnitX; // advance in standard way to the right } // checking the automatic calculated game position with section width if (gi.PositionX >= sectionWidthHeight.X) { gi.PositionY += 1; gi.PositionX = 0; } } while (gamesCollection.FindGameAt(gi.Position + childPosOffset) != null); } // update prev item position posPrevious = gi.Position; // apply the section position offset gi.PositionX += (int)childPosOffset.X; gi.PositionY += (int)childPosOffset.Y; // add to collection at specified position gamesCollection.Add(gi); } return(null); // indicate array was last item. } else if (j is JsonObject) { // process single leaf item GardenItem ig = new GardenItem((JsonObject)j); ig.WreckProcessing(); // return null to indicate skip, if not valid 'trainwreck' that this client can handle. if (!ig.IsValidWreck) { return(null); } return(ig); } else { throw new NotImplementedException("Unknown JSON type " + j + " found."); } }
static Task <IJsonType> ConvertJavaScriptObjectToCSharpNestedDictionariesAndLists(object javaScriptObject, bool ignoreErrors) { // Note: This method needs to be "async" because it is // recursive and, in the Simulator, it is not possible // to recursively call "ExecuteJavaScript" (ie. to make // nested synchronous calls to JS). IJsonType result = null; var taskCompletionSource = new TaskCompletionSource <IJsonType>(); Action onCompleted = () => { taskCompletionSource.SetResult(result); }; bool isArray = Convert.ToBoolean(Interop.ExecuteJavaScript("Array.isArray($0)", javaScriptObject)); bool isObject = Convert.ToBoolean(Interop.ExecuteJavaScript(@"(typeof($0) === ""object"")", javaScriptObject)); bool isNumber = Convert.ToBoolean(Interop.ExecuteJavaScript(@"(typeof($0) === ""number"")", javaScriptObject)); bool isBoolean = Convert.ToBoolean(Interop.ExecuteJavaScript(@"(typeof($0) === ""boolean"")", javaScriptObject)); bool isNullOrUndefined = Convert.ToBoolean(Interop.ExecuteJavaScript(@"($0 === undefined || $0 === null)", javaScriptObject)); if (isNullOrUndefined) { result = null; onCompleted(); } else if (isArray) { int arrayItemsCount = Convert.ToInt32(Interop.ExecuteJavaScript(@"$0.length", javaScriptObject)); result = new JsonArray(); if (arrayItemsCount > 0) { int currentIndex = 0; Action <object> methodToAddObject = async(jsObj) => { ((JsonArray)result).Add(await ConvertJavaScriptObjectToCSharpNestedDictionariesAndLists(jsObj, ignoreErrors)); currentIndex++; if (currentIndex == arrayItemsCount) { onCompleted(); } }; // Note: the following JS call must be asynchronous because // this algorithm is recursive and, in the Simulator, it is // not possible to recursively call "ExecuteJavaScript" // (ie. to make nested synchronous calls to JS). Interop.ExecuteJavaScriptAsync(@" var input = $0; var methodToAddObject = $1; for (var i = 0; i < input.length; i++) { methodToAddObject(input[i]); }", javaScriptObject, methodToAddObject); } else { onCompleted(); } } else if (isObject) { int keysCount = Convert.ToInt32(Interop.ExecuteJavaScript(@"Object.keys($0).length", javaScriptObject)); result = new JsonObject(); if (keysCount > 0) { int currentIndexInKeys = 0; Action <object, object> methodToAddObject = async(key, jsObj) => { ((Dictionary <string, object>)result)[key.ToString()] = await ConvertJavaScriptObjectToCSharpNestedDictionariesAndLists(jsObj, ignoreErrors); currentIndexInKeys++; if (currentIndexInKeys == keysCount) { onCompleted(); } }; // Note: the following JS call must be asynchronous because // this algorithm is recursive and, in the Simulator, it is // not possible to recursively call "ExecuteJavaScript" // (ie. to make nested synchronous calls to JS). Interop.ExecuteJavaScriptAsync(@" var input = $0; var methodToAddObject = $1; for (var key in input) { var str = key.toString(); //alert(""key: "" + str); methodToAddObject(str, input[key]); }", javaScriptObject, methodToAddObject); } else { onCompleted(); } } else if (isNumber) { result = new JsonValue(Convert.ToDouble(javaScriptObject)); onCompleted(); } else if (isBoolean) { result = new JsonValue(Convert.ToBoolean(javaScriptObject)); onCompleted(); } else { result = new JsonValue(javaScriptObject.ToString()); onCompleted(); } return(taskCompletionSource.Task); }
/// <summary> /// parse a JsonArray (array of items) or JsonObject (single game/item) /// </summary> protected GardenItem ParseJson(IJsonType j, Vector2 posOffset) { if (j is JsonArray) { JsonArray ja = j as JsonArray; Vector2 childPosOffset = posOffset; Vector2 posPrevious = Vector2.Zero; //Vector2 childPosPrevious = Vector2.Zero; Vector2 sectionWidthHeight = new Vector2(999f, 999f); GardenItem gi = null; foreach (IJsonType jChild in ja) { // parse each subitem and add to gamelist gi = ParseJson(jChild, childPosOffset); if (gi == null) continue; // optional first SectionID item of a JsonArray may contain position offset info for all items if (gi.IsSectionId) { childPosOffset += gi.Position; // WARNING mis-use the posdelta field for section width/height!! sectionWidthHeight = gi.PositionDelta; //childPosPrevious = Vector2.Zero; posPrevious = Vector2.Zero - Vector2.UnitX; // for first item of a section, apply a shift to align item to (0,0) continue; } // calculate correct item position if (!gi.IsPositionGiven) { gi.Position = posPrevious; do { if (gi.IsPositionDeltaGiven) gi.Position += gi.PositionDelta; else gi.Position += Vector2.UnitX; // advance in standard way to the right // checking the automatic calculated game position with section width if (gi.PositionX >= sectionWidthHeight.X) { gi.PositionY += 1; gi.PositionX = 0; } } while (gamesCollection.FindGameAt(gi.Position + childPosOffset) != null); } // update prev item position posPrevious = gi.Position; // apply the section position offset gi.PositionX += (int) childPosOffset.X; gi.PositionY += (int) childPosOffset.Y; // add to collection at specified position gamesCollection.Add(gi); } return null; // indicate array was last item. } else if (j is JsonObject) { // process single leaf item GardenItem ig = new GardenItem((JsonObject)j); return ig; } else throw new NotImplementedException("Unknown JSON type " + j + " found."); }