I build a navigation tree and save the structure using this function in an array
function parseTree(html) {
var nodes = [];
html.parent().children("div").each(function () {
var subtree = $(this).children("div");
var item = $(this).find(">span");
if (subtree.size() > 0)
nodes.push([item.attr("data-pId"), item.attr("data-id"), parseTree(subtree)]);
else
nodes.push(item.attr("data-pId"), item.attr("data-id"));
});
return nodes;
}
Then I serialize the data
var tree = $.toJSON(parseTree($("#MyTree").children("div")));
Get this array
[
["881150024","881150024",
[
"994441819","881150024",
"214494418","881150024"
]
],
["-256163399","-256163399",
[
"977082012","-256163399",
"-492694206","-256163399",
[
"1706814966","-256163399",
["-26481618","-256163399"]
]
]
]
]
And send it by ajax
$.ajax({
url: "Editor/SerializeTree",
type: "POST",
data: { tree: tree },
success: function (result) {
alert("OK");
}
});
Question: How do I Deserialize this JSON with JavaScriptSerializer in C#?
Here it seems like you've got an array of nodes and each node has a set of strings or another array of nodes, right? The first thing you could do is just deserialize this to a List<object> like so:
string treeData = "..."; // The JSON data from the POST
JavaScriptSerializer js = new JavaScriptSerializer();
List<object> tree = js.Deserialize <List<object>>(treeData);
This will turn your JSON into a list of objects, though you'll need to manually figure out what is what (if each object a string or another List<object>).
Generally, though, it helps to have some kind of class or struct to represent the "schema" for the the data you are giving the serializer, but it's a bit more work than the above.
In this instance, you'd need your input data to be an actual JSON object rather than just an array. Say you have this JSON (based on the above data):
{id: "root", children: [
{id: "881150024"},
{id: "881150024", children: [
{id: "994441819"}, {id: "881150024"}]},
{id: "-256163399"},
{id: "-256163399", children: [
{id: "-492694206"},
{id: "-256163399", children: [
{id: "1706814966"},
{id: "-256163399", children: [
{id: "-26481618"}, {id: "-256163399"}]}
]}]}]}
If you have a class like this:
public class Node
{
public String id;
public List<Node> children;
}
You can then do something like:
string treeData = "..."; // The JSON data from the POST
JavaScriptSerializer js = new JavaScriptSerializer();
Node root = js.Deserialize<Node>(treeData);
That will be much easier to work with in code.
Taking into account answer by #_rusty.
In MVC3 it is possible to bing JSON data into actions, so your controller code would be very simple
[HttpPost]
public void SerializeTree(IList<Node> tree)
{
// tree is deserialized JSON here
}
For those rare few of us still using VB.Net here and there:
Imports System.Web.Script.Serialization
'wsvcResponse<string> contains the following JSON object: { "foo":"bar", "foo2": { "bar2": "foobar" } }
Dim jsSerializer As New JavaScriptSerializer()
Dim jsonObject As List(Of Object) = jsSerializer.Deserialize(Of Object)(wsvcResponse)
Dim foo As String = jsonObject("foo").ToString ' "bar"
Dim bar2 As String = jsonObject("foo2")("bar2").ToString ' "foobar"
Related
I would like to dynamically create c# object based on the the consumed Json. I do not care about this json but simply would like pick out properties that I need.
I dont know if its best practice to use dynamic keyword and based on the created object I can create a whole new json structure.
How can I desearilize nested objects. Example json:
{
'name': 'James',
'Profile': {
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
},
}
Here is a simple attempt.
var test = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(test.ToString());
I can create object list however when I begin Parent/Child objects I cant seem to get it to work.
Below JSON works fine as an output:
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
}
Desired Output
{
'name': 'James',
'Profile': {
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
},
'Profile': {
'body': {
'id': 'Employee2',
'type': 'Employee',
'attributes': {
props...
},
'job': {
props..
},
'team': [],
}
}
How can I deserialize nested objects?
You can use the json class with following this line of code
dynamic data = Json.Decode(json);
You can use JsonConvert:
dynamic myNewObject = JsonConvert.DeserializeObject(json);
And then, you can access json properties like this:
myNewObject.Profile.body.id
No repro. The string is already deserialized. test contains the entire graph. The expected output is produced as long as a valid JSON string is used :
This snippet :
var json=#"{
'name': 'James',
'Profile': {
'body': {
'id': 'Employee1',
'type': 'Employee',
'attributes': {
'a':3
},
'job': {
'a':3
},
'team': [],
},
}";
var x=JsonConvert.DeserializeObject<object>(json);
Console.WriteLiine(x.ToString());
Produces :
{
"name": "James",
"Profile": {
"body": {
"id": "Employee1",
"type": "Employee",
"attributes": {
"a": 3
},
"job": {
"a": 3
},
"team": []
}
}
}
From the comments though, it looks like the actual JSON string isn't a valid JSON string and throws an exception :
I get Newtonsoft.Json.JsonReaderException: 'Additional text encountered after finished reading JSON content: ,. Path '', line 21, position 13.'
This error points to the actual location in the JSON string that caused the problem. Perhaps there's an extra character there? Perhaps the text contains multiple JSON strings instead of one? The following string is not valid JSON - JSON can't have more than one root objects :
{ "a":"b"}
{ "c":"d"}
Logging tools, event processing and analytic software though store multiple JSON strings per file this way because it only needs an append operation, doesn't require parsing the entire text to produce results and makes partitioning easier. That's still invalid JSON though that has to be read and processed one line at a a time.
You many find this described as "streaming JSON", precisely because you can process the data in a streaming fashion. Instead of loading and parsing a 100MB event file, you can load and process a single line at a time eg:
IEnumerable<string> lines=File.ReadLines(pathToBigFile);
foreach(var line in lines)
{
var myObject=JsonConvert.DeserializeObject<someType>(line);
//do something with that object
}
File.ReadLines returns an IEnumerable<string> that only loads a single line on each iteration. Instead of loading the entire 100MB file, only one line is loaded and parsed each time.
I use different urls get similar json data.
So that I can get more information in the same model
It has trouble me for a long time
i tried to use json.net for a single list.
string url1= "https://apt.data2.com";
string url2= "https://apt.data1.com";
var json1= webClient.DownloadString(url1);
var json2= webClient.DownloadString(url2);
These calls return multiple json objects with the same structure
{
data: [
{
created_time: "1457332172",
text: "什麼東西",
from: {
username: "d86241",
profile_picture: "https://scontent.cdninstagram.com/t51.2885-19/s150x150/11371189_421316874725117_327631552_a.jpg",
id: "397355082",
full_name: "Jhao-wei Hvang"
},
id: "1200511729352353899"
}
]
}
and
{
data: [
{
created_time: "1111",
text: "hi",
from: {
username: "22",
profile_picture: "",
id: "ss",
full_name: "Hvang"
},
id: "1200511352353899"
}
]
}
I want to combine these objects to produce
{
data:[
{
created_time:"1234"
text:...
....
......
},
id:1234....
]
data:[
{
created_time:"4567"
text:....
....
......
},
id:4567....
]
}
How do I merge these into a single json object?
#foreach (var item in Model)
{
# Item.text
}
var jObject1 = // Your first json object as JObject
var jObject2 = // Your second json object as JObject
jObject1.Merge(jObject2);
I am POSTing a JSON object to a controller action:
$.ajax({
url: "/path/to/action",
type: "POST",
dataType: "json",
data: {
name: "John Doe",
phone: "2323454543",
skills: {
code: "php",
design: "photoshop"
}
}
});
How can I map this data to some kind of key-value pair object? In PHP, these get mapped to an associative array invisibly. I would like to be able to access properties like this:
SomeDynamicType data = ...//something here to prepare json data
string codeSkills = data.skills.code; //codeSkills should = "php"
I'm not interested in model binding since these value do not correspond to a model - they are arbitrary.
In your .ajax call stringify Json:
data: {
json:
JSON.stringify({
name: "John Doe",
phone: "2323454543",
skills: {
code: "php",
design: "photoshop"
}
})
}
And accessing properties how you wanted in your controller:
[HttpPost]
public JsonResult Action(string json)
{
dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
string codeSkills = data.skills.code;
...
codeSkills is "php" string.
Newtonsoft Json library is available since .NET 4, if I recall correct.
Try using JSON.NET, this library parses JSON into a dictionary-like structure. It is used as follows:
JObject rss = JObject.Parse(json);
string codeSkills = (string)rss["skills"]["code"];
Hi I am generating a JSON on my API that I am trying to use on codebehind C# in my web application but I cannot deserialize well.
My JSON has an object with JSON arrays and the element inside the array are dynamic so I cannot create a fixed class with those items becuase my JSON can have N ITEMS.
{
"MAINOBJET": [{
"ITEM1": "23800",
"ITEM2": "Dahl; Police",
"ITEM3": "test#test.net"
},
{
"ITEM1": "23802",
"ITEM2": "Steve ; Police",
"ITEM3": "test2#test.net"
}]
}
So how can I deserialize it to a DataTable, list or a Dictionary?
Thank you
here you can do some thing like the following this example should be able to get you started .. replace the structure / example with your Jason Text
lets say that my JSON Script looks like the following
{
"some_number": 253.541,
"date_time": "2012-26-12T11:53:09Z",
"serial_number": "SN8675309"
"more_data": {
"field1": 1.0
"field2": "hello JSON Deserializer"
}
}
assign you JSON jsonText to a variable and pass it to the following C# Code
using System.Web.Script.Serialization;
var jsonSerialization = new JavaScriptSerializer();
var dictObj = jsonSerialization.Deserialize<Dictionary<string,dynamic>>(jsonText);
Console.WriteLine(dictObj["some_number"]); //outputs 253.541
Console.WriteLine(dictObj["more_data"]["field2"]); //outputs hello JSON Deserializer
I have following json created after I sereliaze a dictionary
{"Results":["{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}","{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}","{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}","{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}"],"Total":4}
When I try to load it into the extjs store , the store is not loaded
var store = Ext.create('Ext.data.Store', {
fields: fields,
pageSize: itemsPerPage,
proxy: {
type: 'ajax',
url: getDataWithPageURL,
reader: {
type: 'json',
root: 'Results',
totalProperty: 'Total'
}
}
});
But if I remove slash hard coded and it's working
{"Results":["{"BaseCurrency":"USD","TermCurrency":"JPY"}","{"BaseCurrency":"USD","TermCurrency":"JPY"}","{"BaseCurrency":"USD","TermCurrency":"JPY"}","{"BaseCurrency":"USD"}"],"Total":4}
I create json using Newtonsoft.Json
Dictionary<string, object> dict = new Dictionary<string, object>();
string s = JsonConvert.SerializeObject(dist);
How can I remove slash in server side in order to produce valid json for extjs store.
I tried
result = result.Replace("\"","'");
And
result =result.Replace("\"", #"""")
It's not working
Clearly, Ext doesn't like that you have encoded a json object as a string and then put them in another json object. You have two options that I see.
See if you can return the dict on the server-side without first converting it into a string. Some code, somewhere, is taking your string and putting it in a json object with 'Results' and 'Total'. Check to see if that code can take a Dictionary as-is.
Unwrap the 'Results' propery on the client-side. One way would be to make your own reader:
Ext.define('MyReader', {
extend: 'Ext.data.reader.Json',
alias: 'reader.my-json',
read: function(object) {
object.Results = Ext.Array.map(object.Results, Ext.decode);
return this.callParent([object]);
}
});
Then use type: 'my-json' in your reader config.
Here is my test case:
var data = {"Results":["{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}","{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}","{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}","{\"BaseCurrency\":\"USD\",\"TermCurrency\":\"JPY\"}"],"Total":4};
Ext.define('Currency', {
extend: 'Ext.data.Model',
fields: [
{ name: 'BaseCurrency', type: 'string' },
{ name: 'TermCurrency', type: 'string' }
]
});
Ext.define('MyReader', {
extend: 'Ext.data.reader.Json',
alias: 'reader.my-json',
read: function(object) {
object.Results = Ext.Array.map(object.Results, Ext.decode);
return this.callParent([object]);
}
});
var store = Ext.create('Ext.data.Store', {
model: 'Currency',
data: data,
proxy: {
type: 'memory',
reader: {
type: 'my-json',
root: 'Results',
totalProperty: 'Total'
}
}
});