I have these data in thhe codebehind and tried to pass it to javascript function in various formats: array of list, json string but no way to get data by a javascript var object.
Here is the last format of data in the code behind:
List<string>[] array2 = new List<string>[listLenght];
array2.Initialize();
for (int ii = 0; ii < listLenght; ii++)
{
array2[ii] = new List<string>();
array2[ii].Add(Convert.ToString(dt.Rows[ii][5]));
array2[ii].Add(Convert.ToString(dt.Rows[ii][9]));
array2[ii].Add(Convert.ToString(dt.Rows[ii][10]));
array2[ii].Add(Convert.ToString(dt.Rows[ii][11]));
}
Then tried to call javascript in this way:
string createArrayScript = string.Format("var array2 = [{0},{1},{2},{3}];",
string.Join(",",",",",", array2));
But returns an error:
FormatException was unhandled by user code.The index (zero based) must be greater than or equal to zero and less than the size of the list of topics
This is the call to the function:
Page.ClientScript.RegisterStartupScript(this.GetType(), "registerPoiArray", createArrayScript, true);
Here is the javascript var format:
var markers = Poi;
var markers = [
{
"title": "via Andria, Roma",
"lat": 41.8902643,
"lng": 12.6638589,
"description": "fdsad"
},
{
"title": "via canosa, Roma",
"lat": 41.8838417,
"lng": 12.5438227,
"description": "fdsad"
},
{
"title": "via taranto, Milano",
"lat": 45.4383343,
"lng": 9.1505354,
"description": "fdsad"
},
{
"title": "via barletta, Roma",
"lat": 41.9102707,
"lng": 12.4580826,
"description": "fdsad"
}];
I can not pass this array in javascript.
You can create a custom class to represent the Datatable. Say if your data table has four columns, create a custom class which has 4 fields in it. Loop through the data table and convert it in to an array of objects of the custom class type.
Finally you can serialize the array into json using the following code.
JavaScriptSerializer js = new JavaScriptSerializer();
js.Serialize(data);
where data is the array of objects.
This is the technique i used..
Data table cannot be serialized easily to JSON directly. refer What's the best way to jSON serialize a .NET DataTable in WCF?
You have to escape (double up) the curly brace when using String.Format if you want it to spit out the actual curly brace character.
Example:
string createArrayScript =
string.Format("var array2 = [{{0}},{{1}},{{2}},{{3}}];",
...
Try to use
System.Web.Helpers.Json.Encode
And change the structure you are getting.
List<object> toEncode=new List<object>();
foreach (DataRow dr in dt.Rows){
Dictionary<string,string> element=new Dictionary<string,string>();
element.Add("title",dr["title"] as string);
//repeat for all neaded colums
toEncode.Add(element);
}
string jsonString=Json.Encode(toEncode);
I created a gist when I put the solution.
I hope this works for you...
Regards,
Just use NewtonSoft Json and call:
var JsonString = JsonConvert.SerializeObject(NameofDT, Formatting.Indented)
Related
İ want to show json objects in a datatable. (C#.MVC) Due fact that json object have mostly different fileds according machines data they belong. For each json object i dont want to write a seperate class. How can i handle this json objects dynamically and show datatable in a single class?
Thanks in advance.
With Cinchoo ETL, an open source library, you can do it as follows
string json = #"{
""header"": ""myheader"",
""transaction"": {
""date"": ""2019-09-24"",
""items"": [
{
""number"": ""123"",
""unit"": ""EA"",
""qty"": 6
},
{
""number"": ""456"",
""unit"": ""CS"",
""qty"": 4
}
]
}
}";
using (var r = ChoJSONReader.LoadText(json))
{
var dt = r.Select(f => f.Flatten()).AsDataTable();
Console.WriteLine(dt.DumpAsJson());
}
Output:
[
{
"header": "myheader",
"transaction_date": "2019-09-24",
"transaction_items_0_number": "123",
"transaction_items_0_unit": "EA",
"transaction_items_0_qty": 6,
"transaction_items_1_number": "456",
"transaction_items_1_unit": "CS",
"transaction_items_1_qty": 4
}
]
Hope it helps.
I have a JSON string like below:
{
"MetaData": {
"ResourcesUsed": 1
},
"Result": [
{
"locations": [
{
"country": "Papua New Guinea",
"city": "Jacquinot Bay",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-08T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
},{
"country": "Papua New Guinea2",
"city": "Jacquinot Bay2",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-02T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
}
]
}
]
}
I converted it to a JSON object using Newtonsoft. What I want to do is to sort the locations array(s) inside the Result array by the utcDate field nested in each locations item. I found the following thread: C# Sort JSON string keys. However, I could not still implement it since I have arrays inside my object, while that question deals purely with sorting objects inside objects alphabetically by property name.
Here is a piece of code that I wrote so far:
public string GenerateJson()
{
var model = (JObject)JsonConvert.DeserializeObject(data);
Sort(model);
}
private void Sort(JObject jObj)
{
var props = jObj["Result"][0]["locations"].ToList();
foreach (var prop in props)
{
prop.Remove();
}
foreach (var prop in props.OrderBy(p => p.Name))
{
jObj.Add(prop);
if (prop.Value is JObject)
Sort((JObject)prop.Value);
if (prop.Value is JArray)
{
Int32 iCount = prop.Value.Count();
for (Int32 iIterator = 0; iIterator < iCount; iIterator++)
if (prop.Value[iIterator] is JObject)
Sort((JObject)prop.Value[iIterator]);
}
}
}
You can sort each individual "Result[*].locations" array using LINQ as follows:
// Load the JSON without parsing or converting any dates.
var model = JsonConvert.DeserializeObject<JObject>(data, new JsonSerializerSettings{ DateParseHandling = DateParseHandling.None });
// Construct a serializer that converts all DateTime values to UTC
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings{ DateTimeZoneHandling = DateTimeZoneHandling.Utc });
foreach (var locations in model.SelectTokens("Result[*].locations").OfType<JArray>())
{
// Then sort the locations by utcDate converting the value to UTC at this time.
var query = from location in locations
let utcDate = location.SelectToken("locTypeAttributes.utcDate").ToObject<DateTime>(serializer)
orderby utcDate
select location;
locations.ReplaceAll(query.ToList());
}
Notes:
The JSON is initially loaded using DateParseHandling.None to prevent the "localDate" and "utcDate" strings from being prematurely interpreted as DateTime objects with a uniform DateTime.Kind.
(For a discussion of how Json.NET interprets strings that look like dates, see Serializing Dates in JSON.)
We then iterate through all "locations" arrays using SelectTokens("Result[*].locations") where [*] is the JSONPath wildcard character, selecting all entries in the "Results" array.
We then order each "locations" array by deserializing the nested locTypeAttributes.utcDate to a UTC date, then ordering using LINQ.
Finally the array is updated using JArray.ReplaceAll().
If any locTypeAttributes.utcDate property is missing, an exception will be thrown. You could instead deserialize to DateTime? if that is a possibility.
Working sample .Net fiddle here.
I am getting an array when I deserialize my JSON.
I can access the array with foreach.
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
foreach (dynamic result in obj.Results.output1.value.Values)
{
}
But I need to get size of the array to access the last element direct.
Eg.
obj.Results.output1.value.Values[size-1]
How can I do that?
Edit 1
I need to get for example the "Y" in "Values"
{
"Results": {
"output1": {
"type": "table",
"value": {
"ColumnNames": [
"I01",
"I02",
"I03",
"O01",
"Scored Probabilities for Class \"0\"",
"Scored Probabilities for Class \"1\"",
"Scored Probabilities for Class \"2\"",
"Scored Labels"
],
"Values": [
[
"-0.96624",
"0.02918",
"-0.44237",
null,
"3.25456957391002E-12",
"0.000107838139228988",
"2.76633869589205E-07",
"Y"
]
]
}
}
}
}
Edit 2
If I print I get this JSON
Console.WriteLine(obj.Results.output1.value.Values);
[
[
"-0.96624",
"0.02918",
"-0.44237",
null,
"3.25456957391002E-12",
"0.000107838139228988",
"2.76633869589205E-07",
"Y"
]
]
And the Count prints 1
Console.WriteLine(obj.Results.output1.value.Values.Count);
I almost there, I need the last element o the size to access by index in the inside array.
Edit 3
I could get the last element with:
Console.WriteLine(obj.Results.output1.value.Values[0].Last);
And the array size with:
Console.WriteLine(obj.Results.output1.value.Values[0].Count);
The JSON shows that Results is an object, not an array or list. What you're iterating is the properties. It's not a collection. It will be a JObject, which exposes .Last.
See here for more information
You simply need to write:
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var lastProperty = obj.Last;
Might be useful to cast to a JObject (or a Dictionary<string, object> as well to help with future issues.
JObject obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
Accessing Values:
dynamic thing = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var t = thing.Results.output1.value.Values.Count;
Here is the sample, I can get the result of 100.
ICollection collection = new int[100];
dynamic obj = collection;
Console.WriteLine(obj.Length);
int[] foo = new int[10];
int n = foo.Length;
you can get array size using ( arrayname.lenth ).try it.
So I what I am trying to do is capture/extract specific data from Steams API for dota2 heroes. I am using C# to do this with this method.
https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=2D13D618DA712015812E970165632F02&language=en_us
{
"result": {
"heroes": [
{
"name": "npc_dota_hero_antimage",
"id": 1,
"localized_name": "Anti-Mage"
},
]
}
This is the code I have been trying with:
WebClient c = new WebClient();
var data = c.DownloadString("https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=2D13D618DA712015812E970165632F02&language=en_us");
JObject o = JObject.Parse(data);
string heroname = (string)o["name"];
But it only returns an error saying the value of "heroname" is null.
Any ideas?
o is going to be an object that contains one key: result. o["result"] will in turn contain a key called heroes. o["result"]["heroes"] is an array of objects. So o["result"]["heroes"][0] will be the first item, and o["result"]["heroes"][0]["name"] is the name from the first item.
I have some code in JavaScript like this:
slider.setPhotos([
{ "src": "image1", "name": "n1" },
{ "src": "image2", "name": "n2" },
{ "src": "image3", "name": "n3" }
]);
And I want to set the values of src and name from C#.
Assume values are like this in C#:
var images = new string[] {"/images/a1.jpg", "/images/a2.jpg", "/images/a3.jpg"};
var names = new string[] {"First", "Second", "Third"};
How can I set these values into JavaScript code (i.e. in Page Load method in C# code)?
On the server you need to serialize the data as JSON and then you can write it into the response as HTML using something like a hidden input field.
For example you might use the NewtonSoft JSON library to serialize the JSON (which is built into ASP MVC 4 however is easy to install using Nuget)
string json = Newtonsoft.Json.JsonConvert.SerializeObject(images);
Then render the json into the HTML (there are number of methods to do this)
e.g.
Response.Write(string.Concat("<input id='data' type='hidden' value='", json, "' />");
or
HiddenField jsonField = new HiddenField
{
ID = "data"
};
jsonField.Value = json;
this.Controls.Add(jsonField);
or even write directly as script skipping the need to parse on the client (I still tend to use the HTML method to avoid any issues with Postbacks/Update Panels causing the script to be executed multiple times)
Response.Write(string.Concat("<script type='text/javascript'> var images = ", json, ";</script>");
On the client you can then read this JSON from the HTML and parse it. In modern browsers this is built in, or you can polyfill with something like JSON2
e.g.
var field = document.getElenentById('data');
var images = JSON.parse(field.value);
You then have access to the data as a Javascript object.
Assuming that images and names are of same length
You can use this
StringBuilder str = new StringBuilder();
var images = new string[] {"/images/a1.jpg", "/images/a2.jpg", "/images/a3.jpg"};
var names = new string[] {"First", "Second", "Third"};
str.AppendLine("slider.setPhotos([");
for(int i=0; i< images.Length; i++)
{
str.AppendLine("{ \"src\": "+ images[i] +", \"name\": "+ names[i] +" }");
str.AppendLine( (i==images.Length-1 ? "]);":","));
}
Page.ClientScript.RegisterClientScriptBlock(
this.GetType(), "Key007", str.ToString(), true);
This code will insert a script block when your page will be loaded and after that you can use that script block anywhere in your client side code.