I am using Newtonsoft and Newtonsoft.Json. I have the below json:
string strJson_StorageInfo = "[{10:\"test\"}, {20:\"test1\"}]";
List<Dictionary<int, string>> jobj = (List<Dictionary<int, string>>) JsonConvert.DeserializeObject(strJson_StorageInfo, typeof(List<Dictionary<int, string>>));
foreach (Dictionary<int, string> dicStorageInfo in jobj) {
foreach (KeyValuePair<int, string> StorageItem in dicStorageInfo) {
Response.Write("key : " + StorageItem.Key + " , value : " + StorageItem.Value + "</br>");
}
}
I need to Deserialize this. Can anyone suggest me good method. Thanks in advance
you can use below mentioned code
string strJson_StorageInfo = "[{10:\"test\"}, {20:\"test1\"}]";
var abc = JsonConvert.DeserializeObject <List<Dictionary<int, string>>>(strJson_StorageInfo);
after you can find the keys and Values from it
var K = abc.Select(p => p.Keys);
var V = abc.Select(p => p.Values);
ok. I compromised with Json Format String. I have changed the json string. Found similar thread in How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?. Thanks.
This worked for me.. I am not sure if it works in asp.net 2.0
string strJson_StorageInfo = "[{10:\"test\"}, {20:\"test1\"}]";
List<Dictionary<int, string>> values = JsonConvert.DeserializeObject<List<Dictionary<int, string>>>(strJson_StorageInfo);
foreach (var items in values)
{
foreach (var item in items)
{
Label1.Text += "Key: " + item.Key.ToString() + " Value: " + item.Value.ToString() + "<br/>";
}
}
Related
I'm able to get a dynamic Json object using
dynamic obj = JsonConvert.DeserializeObject(json);
It seems to be a nested object structure
I need to graph every variable in the json file, but the json file structure changes often
Is there a way to parse through this structure using nested foreach() statements?
If not, can can I parse it by accessing each element via a string like a Dictionary?
for example something like:
if(obj["Item1"]["Parameter3"]["Value2"]` != NULL)
int number = obj["Item1"]["Parameter3"]["Value2"]`
Thanks,
Yes there is an API for querying dynamically.
See the documentation here: https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm
Code looks something like this:
JObject rss = JObject.Parse(json);
var postTitles =
from p in rss["channel"]["item"]
select (string)p["title"];
Finally figured this api out
Some JToken entries have a list of values, others have a name and value. You have to sort which one is which prior to parsing it.
This will create a Dictionary with every entry in the Json file
void SomeFunction()
{
Dictionary<string, decimal> json_data = new Dictionary<string, decimal>();
dynamic json_obj = JsonConvert.DeserializeObject(json);
Linearize(ref json_data, json_obj);
}
void Linearize(ref Dictionary<string, decimal> input_dict, JToken json_data, string key = "")
{
int i;
if (json_data != null)
{
if (json_data.HasValues)
{
i = 0;
foreach (dynamic entry in json_data)
{
//Add a Name field if it exists
Type typeOfDynamic = entry.GetType();
if (typeOfDynamic.GetProperties().Where(p => p.Name.Equals("Name")).Any())
key += entry.Name + ".";
//If JToken is an Array
if (((JToken)entry).HasValues)
{
Linearize(ref input_dict, entry, key + "[" + i++ + "]" + ".");
}
//If JToken is a data type
else if (entry.Type == JTokenType.String || entry.Type == JTokenType.Float || entry.Type == JTokenType.Integer)
{
decimal output;
if (decimal.TryParse(entry.ToString(), out output))
input_dict.Add(key + "[" + i++ + "]", output);
}
}
}
}
}
I'm working on a project where I want to build tokens from a JSON Array.
//Data fed to the system
{"Fruits":[{"Number":"111", "Name":"Apple"}, {"Number":"112", "Name":"Orange"},{"Number":"113", "Name":"Peach"}]}
//serializes the http content to a string
string result = Request.Content.ReadAsStringAsync().Result;
//deserializes result
Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(result);
//builds custom tokens
var customTokens = new Dictionary<string, object>();
foreach (var dataField in data)
{
if (dataField.Value is JArray)
{
string nameValue = "";
foreach (JObject content in dataField.Value.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
nameValue += prop.Name.ToString() + " : " + prop.Value.ToString();
}
}
customTokens.Add($"{dataField.Key}", nameValue);
}
}
The above code managed to create token $Fruits.
But i also want to achieve token $Number and $Name, where values of each token is from the concatenated values of same key. Example, If I use the "$Number", it will be replaced by 111, 112, 113 and If I use the $Name, it will be replaced by Apple, Orange, Peach.
Also, I'm not using any strongly type models as I don't know what data will be fed to the system.
Any help?
There are a few minor changes to your code to achieve this. First make your dictionary look like this:
var customTokens = new Dictionary<string, List<string>>();
Then, when you loop over all the properties in the array, check if the property has been added, and if not add it.
foreach (JProperty prop in content.Properties())
{
if(customTokens.ContainsKey(prop.Name))
{
customTokens[prop.Name].Add(prop.Value.ToString());
}
else
{
customTokens.Add(prop.Name, new List<string> { prop.Value.ToString() });
}
}
At the end you have a dictionary where the key is the property name and the value is a List<string> - this can be concatenated together:
foreach(var item in customTokens)
{
Console.WriteLine(item.Key + ":" + String.Join(",", item.Value));
}
Or, if you really want it in a dictionary of concatenated strings just do this
var finalResult = customTokens.ToDictionary(k => k.Key, v => String.Format(",",v.Value));
Note you'll need to add using System.Linq to the top of your file to use ToDictionary
Final test code:
var result = "{ \"Fruits\":[{\"Number\":\"111\", \"Name\":\"Apple\"}, {\"Number\":\"112\", \"Name\":\"Orange\"},{\"Number\":\"113\", \"Name\":\"Peach\"}]}";
Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(result);
var customTokens = new Dictionary<string, List<string>>();
foreach (var dataField in data)
{
if (dataField.Value is JArray)
{
foreach (JObject content in dataField.Value.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
if(customTokens.ContainsKey(prop.Name))
{
customTokens[prop.Name].Add(prop.Value.ToString());
}
else
{
customTokens.Add(prop.Name, new List<string> { prop.Value.ToString() });
}
}
}
foreach(var item in customTokens)
{
Console.WriteLine(item.Key + ":" + String.Join(",", item.Value));
}
}
}
How could you convert a string of JSON to a C# NameValueCollection simply, preferably without using a 3rd party parser?
I'm not sure why everyone is still recommending JSON.NET for deserialization of JSON. I wrote a blog post on how to deserialize JSON to C#.
In short, it's like this:
using System.Web.Script.Serialization;
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string, string>>(jsonText);
NameValueCollection nvc = null;
if (dict != null) {
nvc = new NameValueCollection(dict.Count);
foreach (var k in dict) {
nvc.Add(k.Key, k.Value);
}
}
}
var json = jss.Serialize(dict);
Console.WriteLine(json);
Be sure to add a reference to System.Web.Extensions.dll.
Note:
I usually deserialize to dynamic, so I'm assuming that NameValueCollection would work. However, I haven't verified if it actually does.
EDIT
Pure .net solution without third party development have look : JavaScriptSerializer – Dictionary to JSON Serialization and Deserialization
make use of Json.NET
string jsonstring = #"{""keyabc"":""valueabc"",""keyxyz"":""valuexyz""}";
Dictionary<string, string> values =
JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonstring);
Check #jon answer suggest same : .Net Linq to JSON with Newtonsoft JSON library
If your JSON contains nested objects whithin it the solution below will handle them properly (based on JSON.NET, but you can adapt to the JSON parser of your choice).
This usage example:
var json = "{\"status\":\"paid\",\"date\":\"2019-10-09T17:30:51.479Z\",\"customer\":{\"id\":123456789,\"country\":\"br\",\"name\":\"Thomas Vilhena\",\"phone_numbers\":[\"+5511987654321\"],\"documents\":[{\"id\":\"doc_id\"}]}}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
var nvc = new NameValueCollection(dict.Count);
AddKeyValuePairs(nvc, dict);
Console.WriteLine(nvc["status"]);
Console.WriteLine(nvc["date"]);
Console.WriteLine(nvc["customer[phone_numbers][0]"]);
Console.WriteLine(nvc["customer[id]"]);
Console.WriteLine(nvc["customer[documents][0][id]"]);
Produces the following output:
paid
09.10.2019 17:30
+5511987654321
123456789
doc_id
And here's the implementation:
private static void AddKeyValuePairs(
NameValueCollection nvc,
Dictionary<string, object> dict,
string prefix = null)
{
foreach (var k in dict)
{
var key = prefix == null ? k.Key : prefix + "[" + k.Key + "]";
if (k.Value != null)
AddKeyValuePair(nvc, key, k.Value);
}
}
private static void AddKeyValuePair(
NameValueCollection nvc,
string key,
object value)
{
if (value is string || value.GetType().IsPrimitive)
{
nvc.Add(key, value.ToString());
}
else if (value is DateTime)
{
nvc.Add(key, ((DateTime)value).ToString("g"));
}
else
{
AddNonPrimitiveValue(nvc, key, value);
}
}
private static void AddNonPrimitiveValue(
NameValueCollection nvc,
string key,
object value)
{
var a = value as JArray;
if (a != null)
{
for (int i = 0; i < a.Count; i++)
AddKeyValuePair(nvc, key + "[" + i + "]", a[i]);
}
else
{
var v = value as JValue;
if (v != null)
{
AddKeyValuePair(nvc, key, v.Value);
}
else
{
var j = value as JObject;
if (j != null)
AddKeyValuePairs(nvc, j.ToObject<Dictionary<string, object>>(), key);
}
}
}
I have fallen into a doubt and I don't know how to solve it, the case is:
I have created an "arrayed string" list like this:
List<string[]> definitions;
I have added to it values like this:
definitions.Add(new string[2] { "A", "Def.1" });
definitions.Add(new string[2] { "B", "Def.2" });
In order to show the values I do it like this:
foreach (string[] theDefinition in definitions)
{
Console.WriteLine(theDefinition[0] + "\tdef: " + theDefinition[1]);
}
So far this works fine, but how can I show the values without the foreach I mean something like this:
Console.WriteLine(definitions[0] ...)
What should I write in the 3 dots to show either the "A" or the "Def.1" from the list in index 0.
I guess overcoming this is by doing something like:
string[] temp = definitions[0]
Console.WriteLine(temp[0] + ", " + temp[1]);
How to achieve it just using the Console.WriteLine without using extra variables, is this possible? and how? Thank you in advance.
Console.WriteLine(definitions[0][0] + "\tdef: " + definitions[0][1]);
The other answers are correct of course but why not just use a Dictionary instead of List of a 2 dimensional string array.
var definitions = new Dictionary<string, string>
{
{ "A", "Def.1" },
{ "B", "Def.2" }
};
foreach (var keypair in definitions)
{
Console.WriteLine("{0} \tdef: {1} ", keypair.Key, keypair.Value);
}
A better way would be to declare a definition type
public class Definition
{
public string Name { get; set; }
public string Value { get; set; }
public override string ToString()
{
return Name + "\tdef: " + Value;
}
}
Now you can simplify your code like this
List<Definition> definitions = new List<Definition> {
new Definition { Name = "A", Value = "Def.1" },
new Definition { Name = "B", Value = "Def.2" },
};
foreach (Definition theDefinition in definitions)
{
Console.WriteLine(theDefinition);
}
Of cause you can use a fluent version of it as proposed by Nikhil Agrawal, which is now even simpler.
definitions.ForEach(def => Console.WriteLine(def));
prints
A def: Def.1
B def: Def.2
And accessing the fields is more descriptive than using array indexes
Definition def = definitions[0];
Console.WriteLine(def.Name + ", " + def.Value);
// compared to
// Console.WriteLine(temp[0] + ", " + temp[1]);
You can access it like this: definitions[definition_index][string_index].
Try:
Console.WriteLine(definitions[0][0] + "\tdef: " + definitions[0][1]);
for (var i = 0; i < definitions.Length; i++)
{
Console.WriteLine(definitions[i][0] + "\tdef: " + definitions[i][1]);
}
One Line Answer instead of 3 Lines. No use of For or foreach Loop or Extra Variable when LINQ is here
definitions.ForEach(x => Console.WriteLine(x[0] + "\tdef: " + x[1]));
public static string filename2_1, filename2_2, filename2_3;
filename2_1="xyz.jpg";
filename2_2="abc.png";
filename2_3="qwe.jpg";
.....
...
for (int key = 1; key <= 3; key++)
{
....
foreach (var item in tabItem)
{
item.ImagePath.Value = "images1/" + ("filename2_" + key);
item.ThumbPath.Value = "thumbnails1/" + ("filename2_" + key);
}
}
As stated above I need to convert ("filename2_" + key) into actual variable. Can anyone help me regarding this
You can't have dynamic variable names.
Variable names cannot be "created".
You can use an array or a generic collection to hold the collections of data you are using.
var fileSuffixList = new List<string>{ "xyz.jpg" , "abc.png", "qwe.jpg"};
foreach(string fileSuffix in fileSuffixList)
{
....
foreach (var item in tabItem)
{
item.ImagePath.Value = "images1/" + ("filename2_" + fileSuffix);
item.ThumbPath.Value = "thumbnails1/" + ("filename2_" + fileSuffix);
}
}
As #Oded stated, you can't have dynamic variable names.
What you can do is use a Collection such as a dictionary:
Dictionary<string, int> dictionary = new Dictionary<string, string>();
dictionary.Add("filename2_" + key, "Value");
If your keys are always numeric, you can also use an array or a List. However, without more information, it's hard to tell you the best way to go about it.