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
I'm trying to send a JSON message to facebook that they call a game.achievement but I wanted to create the object using an AnonymousType before Posting. The problem is one of the fields is "game:points" (with the colon). As you can see I've used the # prefix for the object field but it doesn't work for the game:points field. It gets underlined in red and won't compile.
var paramsJson = new
{
privacy = new { value = "ALL_FRIENDS" },
#object = new
{
app_id = "my app id",
type = "game.achievement",
title = "Test",
#"game:points" = 100,
description = "Test",
image = "img.png"
}
};
I've tried many varieties of #, double quotes etc. Is it possible or do I need to just use a StringBuilder for this?
Why don't you just use a dictionary?
var postData = new Dictionary<string, object>
{
{"game:points", 100}
}
Presumably you're going to have to serialize your object to Post it regardless of how it's constructed. Serializing this to JSON would result in the same structure. Alternatively, just do as other's have suggested and create a class for your payload. You can then use Newtonsoft to indicate alternative names for serialization.
public class GameAchievement
{
[JsonProperty("game:points")]
public int Points {get; set;}
}
From the result of an API call I have a large amount of JSON to process.
I currently have this
Object convertObj = JsonConvert.DeserializeObject(responseFromServer);
I am aware that I could do something like
Movie m = JsonConvert.DeserializeObject<Movie>(responseFromServer);
And then use it like
m.FieldName
m.AnotherField
//etc
Ideally I would like to do something like
var itemName = convertObj["Name"];
to get the first Name value for the first item in the list.
Is this possible, or do I have to create a class to deserialize to?
The reason I do not want to create the class is I am not the owner of the API and the field structure may change.
Edit.
Okay so I created the class as it seems the best approach, but is there a way to deserialize the JSON into a list?
var sessionScans = new List<SessionScan>();
sessionScans = JsonConvert.DeserializeObject<SessionScan>(responseFromServer);
Complains that it cannot convert SessionScan to generic list.
No need to use dynamic, you can simply use JToken which is already does what you expect:
var json = #"
{
""someObj"": 5
}
";
var result = JsonConvert.DeserializeObject<JToken>(json);
var t = result["someObj"]; //contains 5
With .NET 6, this can be done as below,
using System.Text.Json;
using System.Text.Json.Nodes;
string jsonString = #"some json string here";
JsonNode forecastNode = JsonNode.Parse(jsonString)!;
int temperatureInt = (int)forecastNode!["Temperature"]!;
Console.WriteLine($"Value={temperatureInt}");
//for nested elements, you can access as below
int someVal = someNode!["someParent"]["childId"]!.ToString();
Refer this MS docs page for more samples - create object using initializers, make changes to DOM, deserialize subsection of a JSON payload.
You can try with JObject.Parse :
dynamic convertObj = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = convertObj.Name;
string address = convertObj.Address.City;
The below example can deserialize JSON to a list of anonymous objects using NewtonSoft.Json's DeserializeAnonymousType method.
var json = System.IO.File.ReadAllText(#"C:\TestJSONFiles\yourJSONFile.json");
var fooDefinition = new { FieldName = "", AnotherField = 0 }; // type with fields of string, int
var fooListDefinition = new []{ fooDefinition }.ToList();
var foos = JsonConvert.DeserializeAnonymousType(json, fooListDefinition);
You can use Json.NET's LINQ to JSON API
JObject o = JObject.Parse(jsonString);
string prop = (string)o["prop"];
Use Newtonsoft.Json
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var json = "[{'a':'aaa','b':'bbb','c':'ccc'},{'a':'aa','b':'bb','c':'cc'}]";
var ja = (JArray)JsonConvert.DeserializeObject(json);
var jo = (JObject) ja[0];
Console.WriteLine(jo["a"]);
I had this problem working with unknown APIs then I decide to come over this problem using this approach, I'm writing down here my test case:
[TestMethod]
public void JsonDocumentDeserialize()
{
string jsonResult = #"{
""status"": ""INTERNAL_SERVER_ERROR"",
""timestamp"": ""09-09-2019 11:00:24"",
""message"": ""documentUri is required.""
}";
var jDoc = JsonDocument.Parse(jsonResult);
if (jDoc.RootElement.TryGetProperty("message", out JsonElement message))
{
Assert.IsTrue(message.GetString() == "documentUri is required.");
}
}
it worked for me because first I was looking to find a way to use dynamic type as it's mentioned in Azure Function HTTPTrigger. But I found this approach most useful and robust.
Microsoft Reference
I'm parsing a json which has 3 properties that have arrays as values, to my controller. I managed to save the json to a Dictionary, and now i need those 3 arrays to make a query to my database.
The setup is the following
public JsonResult FilterMultiselects(string json)
{
Dictionary<string, string[]> filters = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(json);
string[] lines = filters["lines"];
string[] countries = filters["countries"];
string[] users = filters["users"];
var query = ... //do my query which returns the results i desire
string result = JsonConvert.SerializeObject(query, Formatting.Indented,
new JsonSerializerSettings {
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
return Json(result, JsonRequestBehavior.AllowGet);
}
The problem im having is that when i get to the part in which i initialize those 3 arrays only the second one(countries) exists. The other two dont even create which makes no sense to me. Even thought i have not worked with Dictionaries(hashes) too much in C# it looks good.
Could anyone help me with what am i missing?
The json im parsing has the following look:
{
lines: ["line 1", "line 2"]
countries: ["England"]
users: []
}
The string my controller receives is:
"{\"lines\":[\"line 1\",\"line 2\"],\"countries\":[\"England\"],\"users\":[]}"
The dictionary gets created and has 3 keys that have the correct arrays as values.
I have JSON in the following format:
[
{"id":"10","name":"User","add":false,"edit":true,"authorize":true,"view":true},
{"id":"11","name":"Group","add":true,"edit":false,"authorize":false,"view":true},
{"id":"12","name":"Permission","add":true,"edit":true,"authorize":true,"view":true}
]
How can I convert that into a C# DataTable object as follows?
---------------------------------------------------------------------
ID | Name | Add | Edit | View | Authorize
---------------------------------------------------------------------
10 | User | true | true | true | true
11 | Group | true | true | true | true
12 | Permission| true | true | true | true
There is an easier method than the other answers here, which require first deserializing into a c# class, and then turning it into a datatable.
It is possible to go directly to a datatable, with JSON.NET and code like this:
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
Deserialize your jsonstring to some class
List<User> UserList = JsonConvert.DeserializeObject<List<User>>(jsonString);
Write following extension method to your project
using System.ComponentModel;
public static DataTable ToDataTable<T>(this IList<T> data)
{
PropertyDescriptorCollection props =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for(int i = 0 ; i < props.Count ; i++)
{
PropertyDescriptor prop = props[i];
table.Columns.Add(prop.Name, prop.PropertyType);
}
object[] values = new object[props.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(item);
}
table.Rows.Add(values);
}
return table;
}
Call extension method like
UserList.ToDataTable<User>();
One doesn't always know the type into which to deserialize. So it would be handy to be able to take any JSON (that contains some array) and dynamically produce a table from that.
An issue can arise however, where the deserializer doesn't know where to look for the array to tabulate. When this happens, we get an error message similar to the following:
Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path '', line 1, position 1.
Even if we give it come encouragement or prepare our json accordingly, then "object" types within the array can still prevent tabulation from occurring, where the deserializer doesn't know how to represent the objects in terms of rows, etc. In this case, errors similar to the following occur:
Unexpected JSON token when reading DataTable: StartObject. Path '[0].__metadata', line 3, position 19.
The below example JSON includes both of these problematic features:
{
"results":
[
{
"Enabled": true,
"Id": 106,
"Name": "item 1",
},
{
"Enabled": false,
"Id": 107,
"Name": "item 2",
"__metadata": { "Id": 4013 }
}
]
}
So how can we resolve this, and still maintain the flexibility of not knowing the type into which to derialize?
Well here is a simple approach I came up with (assuming you are happy to ignore the object-type properties, such as __metadata in the above example):
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Linq;
...
public static DataTable Tabulate(string json)
{
var jsonLinq = JObject.Parse(json);
// Find the first array using Linq
var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
var trgArray = new JArray();
foreach (JObject row in srcArray.Children<JObject>())
{
var cleanRow = new JObject();
foreach (JProperty column in row.Properties())
{
// Only include JValue types
if (column.Value is JValue)
{
cleanRow.Add(column.Name, column.Value);
}
}
trgArray.Add(cleanRow);
}
return JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());
}
I know this could be more "LINQy" and has absolutely zero exception handling, but hopefully the concept is conveyed.
We're starting to use more and more services at my work that spit back JSON, so freeing ourselves of strongly-typing everything, is my obvious preference because I'm lazy!
It can also be achieved using below code.
DataSet data = JsonConvert.DeserializeObject<DataSet>(json);
You can make use of JSON.Net here. Take a look at JsonConvert.DeserializeObject method.
I recommend you to use JSON.NET. it is an open source library to serialize and deserialize your c# objects into json and Json objects into .net objects ...
Serialization Example:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string json = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "Expiry": new Date(1230422400000),
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
json = File.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory + "App_Data\\" +download_file[0]);
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
Here is another seamless approach to convert JSON to Datatable using Cinchoo ETL - an open source library
Sample below shows how to convert
string json = #"[
{""id"":""10"",""name"":""User"",""add"":false,""edit"":true,""authorize"":true,""view"":true},
{ ""id"":""11"",""name"":""Group"",""add"":true,""edit"":false,""authorize"":false,""view"":true},
{ ""id"":""12"",""name"":""Permission"",""add"":true,""edit"":true,""authorize"":true,""view"":true}
]";
using (var r = ChoJSONReader.LoadText(json))
{
var dt = r.AsDataTable();
}
Sample fiddle: https://dotnetfiddle.net/y0siCi
I solved it by the following - Used Pravin Pawar's answer below - for converting the JSON object to dt.
https://stackoverflow.com/a/11982180/504351
1)Send the JSON from Angular to C# controller method.
2)In C# Controller method -
convert the string data (JSON object) to a datatable.
DataTable dt = (DataTable)JsonConvert.DeserializeObject(data, (typeof(DataTable)));
3)Create a table in SQL Server database by parsing through rows and columns of the datatable dt
int dt_length = dt.Columns.Count;
Random rand = new Random();
string tablename = "Test" + rand.Next().ToString();
string query = "Create table " + tablename + " ( ";
for (int i = 0; i < dt_length; i ++)
{
if(i == dt_length -1)
{
query = query + dt.Columns[i].ColumnName + " varchar(max) ) ";
}
else
{
query = query + dt.Columns[i].ColumnName + " varchar(max), ";
}
}
4)Similarly insert each of the row data in the table created.
5)This helps to dynamically create a database table from JSON.