Deserialize Json array of array in c# - c#

I am new to c# don't know how to get a JSON array of array stored in a 2d array. I am having a JSON file with students marks like
[
[10,5,4],
[9,6,3]
]
and out of this I am using this code but getting error out at JArray
JArray a = JArray.Parse(json);
I have tried some other approaches as well but nothing helped basically what I want to do is want to create a boolean 2D array which will be populated on the basis of the above JSON record and for that purpose I want to populate the array with JSON content.

With the following valid JSON
{ "data" : [
[10,5,4],
[9,6,3]
]
}
The following class was used to hold the parsed data
public class RootObject {
public IList<IList<int>> data { get; set; }
}
which can be parsed using Json.Net
var root = JsonConvert.DeserializeObject<RoootObject>(json);
and the content accessed
var x1 = root.data[0][1]; // 5
var x2 = root.data[1][1]; // 6

Related

JToken Array to Data Table C#

I have a JSON result with the following structure:
{
"property1":1,
"property2":[[1,"A"],[2,"B"],[3,"C"],...] // Possible to get >10000 values
}
Using the above JSON data format, I am only interested to get the array values from the property2 which contains an array of array values and convert it to data table.
The above JSON result is coming from an external WEB API and here is what I have currently:
var jsonResponse = API.RetrieveData();
JObject json = JObject.Parse(jsonResponse);
JToken[] A = json["property2"].ToArray();
Logically, I can loop on the elements of Array [] A column by column and add it to the predesigned data table. My problem is that, upon using this, the performance will be affected as in most cases, the data that will be retrieved from the API is > 10000 values.
Is there any specific way to convert this kind of JSON Format to DataTable in c# with the most efficient way?
Thank you in advance.
I have Better and Fast approach for You
Step 1
Create a class that is similar to json structure
public class JsonClass
{
public string property1 { get ; set; }
public List<Dictionary<int,string>> property2 { get ; set; }
}
Step 2
Use Newtonsoft and deserialize json input to json match class
JsonClass jsonClass = JsonConvert.DeserializeObject<JsonClass>(jsonInputString);
Step 3
if you are using WPF just use
datatable.ItemSource = jsonClass ;
if you are using Winform then use BindingSource Component
BindingSource binding = new BindingSource();
binding.DataSource = jsonClass;
datatable.DataSource = binding;
Result might be
property1 | property2
---------------------------------------
"A" | Collection
Good luck

Deserialize Json to XML with array of objects contained in single XML node

I need to generate XMLDocument from JObjects, and I'm trying to figure out how to make an array of JObjects convert properly to XML. This is the section giving me trouble:
JObject billsegment = new JObject
{
{"ext_bill_id", bill.ExternalBillID},
{"cust", new JObject
{
{"typ_id_cust","1"},
{"id_cust", bill.CustomerID}
}
},
// This element is giving me trouble
{"bill_line_list", GetBillLines(bill.LineData)}
};
The problem: The resulting XML is:
<bill_line_list>
<bill_line>
<line_no>1</line_no>
<id_elm_bill>06159</id_elm_bill>
</bill_line>
</bill_line_list>
<bill_line_list>
<bill_line>
<line_no>2</line_no>
<id_elm_bill>05432</id_elm_bill>
</bill_line>
</bill_line_list>
Notice there are two <bill_line_list> elements, of which I only want one. I want the result to be:
<bill_line_list>
<bill_line>
<line_no>1</line_no>
<id_elm_bill>06159</id_elm_bill>
</bill_line>
<bill_line>
<line_no>2</line_no>
<id_elm_bill>05432</id_elm_bill>
</bill_line>
</bill_line_list>
My GetBillLines() method returns a JArray, which I formulate like this:
JArray GetBillLines(dynamic lineData)
{
int num_lines = lineData.NumLines;
JArray lines = new JArray();
for (int lineNum = 1; lineNum < num_lines+1; lineNum++)
{
JObject line = new JObject
{
{"line_no", lineNum },
{"id_elm_bill", billData.Lines[lineNum].billCode},
};
lines.Add(new JObject
{
{"bill_line", line}
});
}
return lines;
}
What I've tried: I've tried making the return type of my GetBillLines() to JArray and JToken[], and I've tried returning the JArray with .ToArray(). Also, in my JObject billsegment I've tried changing the last line to
JToken.FromObject(GetBillLines(bill.LineData))
and other various things. I'm wondering why it creates two <bill_line_list>s, since when I create the object I am only adding ONE bill_line_list property, and setting the JToken as an array.
I know that you can force Json arrays when serializing from XML (via json:Array='true'), is there an equivalent the other way around?

How to convert String array containing nested array to JSON in c#

How to convert sub-array to json. I have tried
JArray _extra = JArray.Parse(extra.OrderOfferObject);
if (_extra.Count() > 0)
return Ok(new
{
Data = _extra, // ---
}
So it did convert the string to JArray but skip the inner array. Here's the response:
Data: [{ Category: "Chicken Rice",
Ingredients: "[{ExtraQuantity=1, ExtraPrice=11.99, ExtraTitle=Regular},
{ExtraQuantity=1, ExtraPrice=0.0, ExtraTitle=Stuffed Cheese},
{ExtraQuantity=1, ExtraPrice=0.0, ExtraTitle=Sauce BBQ}}]"}]
How do i convert the inner one, thanks.
Update
var extra = (from orderOffer in extraEntities.ORDER_OFFER
where orderOffer.OrderOfferId == orderOfferId
select new
{
orderOffer.OrderOfferObject
}).FirstOrDefault();
Where OrderOfferObject is an array of string type having nested array.I tried JArray.parse to convert to JsonArray. Alas! it did not convert the nested array, as you can see in response.
Seems like your nested string is in a wrong format.
Currently your string object is this:
{ExtraQuantity=1, ExtraPrice=11.99, ExtraTitle=Regular}
It should be like this:
{ExtraQuantity: 1, ExtraPrice: 11.99, ExtraTitle: Regular}
Once your object is fine. JArray. Parse () only will do the trick.

JSON.NET Array conversion

I am trying to convert a JSON array to a C# dictionary.
My Box class has "id" and "color" properties.
{
"boxes" [
{"id":0, "color":"red"},
{"id":1, "color":"green"},
{"id":2, "color":"blue"}
]
}
I've tried a few things, but haven't had any luck getting this to work yet.
List<Box> jsonResponse = JsonConvert.DeserializeObject<List<Box>>(File.ReadAllText(filePath));
Well the thing is that your Dictionary is in nested property.
And even more - it's not really a dictionary. It is an array of objects where each object consists of two fields - id and color (whereas in dictionary we have key-value pairs).
You could deserialize your json into anonymous object with correct structure and then get the array of boxes out of it and convert it to dictionary:
var box = new { id = 0, name = "" };
var jsonObj = new { boxes = new[] { box } };
var dict = JsonConvert.DeserializeAnonymousType(myJson, jsonObj).boxes
.ToDictionary(b => b.id, b => b.name);
JSON doesn't need {} at the top level - so you can just have your list of items in {}'s surrounded by [].
[
{"id":0, "color":"red"},
{"id":1, "color":"green"},
{"id":2, "color":"blue"}
]

ASP.NET getting indexed values when deserializing JSON into a dynamic object

So I have a JSON string that I am passing from an AJAX call to my controller. I have a list of indexed values that I am passing into a dynamic object.
I deserialize the JSON with
JsonConvert.DeserializeObject<dynamic>(s)
This is the output from that dynamic object:
"RolePermissions[0].RolePermissionId": "269",
"RolePermissions[0].HasAccess": "false",
"RolePermissions[1].RolePermissionId": "270",
"RolePermissions[1].HasAccess": "false",
"RolePermissions[2].RolePermissionId": "271",
"RolePermissions[2].HasAccess": "true",
"RolePermissions[3].RolePermissionId": "272",
"RolePermissions[3].HasAccess": "false"
When I try to access the a property of the object with
ssObj.RolePermissions[0].RolePermissionId
I get a RuntimeBinderException. I have tried to use JObject.Parse, which works great, but for some reason, the values in the array become out of order.
Any help would be greatly appreciated. Thanks!
When you try to do RolePermissions[0].RolePermissionId you are trying to access a nested collection containing an object with a property RolePermissionId at index 0. But your JSON doesn't represent a hierarchy of objects, it represents a single flat object with key/value pairs whose keys contain periods and brackets. Since c# identifiers don't allow such characters so you have no way to access such property values using dynamic directly.
Instead, your options include:
Take advantage of the fact that JsonConvert.DeserializeObject<dynamic>(s) actually returns a JObject and use its dictionary indexer:
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
var rolePermissionId = (string)ssObj["RolePermissions[0].RolePermissionId"];
If you prefer a slightly more typed solution, you could deserialize to a Dictionary<string, dynamic>:
var ssDict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(s);
var rolePermissionId = (string)ssDict["RolePermissions[0].RolePermissionId"];
Or for a much more statically typed solution, parse explicitly to a JObject and use LINQ to JSON:
var jObj = JObject.Parse(s);
var rolePermissionId = (string)jObj["RolePermissions[0].RolePermissionId"];
Sample fiddle showing the various options.
If you are in control of the data being sent via AJAX then make sure the data sent is properly formatted.
In order to be able to deserialize variable s like:
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
and access the resulting object in this manner:
ssObj.RolePermissions[0].RolePermissionId
then the JSON value in s, based on your sample and desired behavior, would have to look like this:
{
"RolePermissions": [
{
"RolePermissionId": "269",
"HasAccess": "false"
},
{
"RolePermissionId": "270",
"HasAccess": "false"
},
{
"RolePermissionId": "271",
"HasAccess": "true"
},
{
"RolePermissionId": "272",
"HasAccess": "false"
}
]
}
This quick unit test showed that it is possible to get indexed values when deserializing JSON into a dynamic object
[TestClass]
public class UnitTest1 {
[TestMethod]
public void GetIndexedValuesWhenDeserializingJSONIntoDynamicObject() {
var s = #"
{
'RolePermissions': [
{
'RolePermissionId': '269',
'HasAccess': 'false'
},
{
'RolePermissionId': '270',
'HasAccess': 'false'
},
{
'RolePermissionId': '271',
'HasAccess': 'true'
},
{
'RolePermissionId': '272',
'HasAccess': 'false'
}
]
}
";
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
var result = ssObj.RolePermissions[0].RolePermissionId;
Assert.AreEqual("269", (string)result);
}
}
So you need to make sure you are sending well formatted JSON to your controller to achieve desired behavior.

Categories