I've read a few posts on how to do this, but everything that i've seen the JSON object has specific property names to query, where i do not.
Here is my JSON string:
{
"424406": true,
"425171": true,
"411961": true
}
I want to loop through the array and read the string and bool field in separately (the JSON string is stored in a hidden variable, then accessed in my asp.net code behind):
dynamic dynObj = JsonConvert.DeserializeObject(partDetailsSelectedItems.Value);
foreach (dynamic x in dynObj)
{
string Id = ????
bool boolValue = ???
}
how do i get each of the 2 objects in "x" without specifying the name?
Ideally, i'd like to convert this stringified JSON into a generic list
List<string,bool>
but i need to understand how to handle my above scenario.
If you use LINQ to JSON it's simple, because JObject allows you to iterate over all the key/value pairs - it implements IEnumerable<KeyValuePair<string, JToken>>:
using System;
using System.IO;
using Newtonsoft.Json.Linq;
class Test
{
public static void Main(string[] args)
{
string text = File.ReadAllText("test.json");
var json = JObject.Parse(text);
foreach (var pair in json)
{
string id = pair.Key;
bool value = (bool) pair.Value;
Console.WriteLine("id: {0}; value: {1}", id, value);
}
}
}
The cast for the value is calling the explicit conversion from JToken to bool. No need for dynamic here at all.
Alternatively, as noted in comments, you can just deserialize to a Dictionary<string, bool>:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
class Test
{
public static void Main(string[] args)
{
string text = File.ReadAllText("test.json");
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, bool>>(text);
foreach (var pair in dictionary)
{
string id = pair.Key;
bool value = pair.Value;
Console.WriteLine("id: {0}; value: {1}", id, value);
}
}
}
I usually end up using LINQ to JSON myself, but either approach works and which is better depends on your context.
Related
I've made a class containing everything from the json file.
Now I want to loop trough every object within this object so I can for fill the application with those values.
I want to scroll trough every CM0xx and use that description:
I hope my goal is clear with that screenshot.
I know that I have to do something like
foreach(CM0XX step in Stepsss)
but that simply wont work.
If making a list<string[]> for it is easier from a json but im clueless for the solution.
this is the code I have now. And the json file ive converted is generated so that should be fine.
string testdata = File.ReadAllText(Application.StartupPath + "\\TestData\\SSH.json");
Root JsonDecoded = JsonConvert.DeserializeObject<Root>(testdata);
testSteps Stepsss = JsonDecoded.SmartShoulder.TestSteps;
foreach (testSteps step in Stepsss)
{
}
this is part of the json. there are alot more CM012
public class CM181
{
public string Name;
public string description;
public string minValue;
public string maxValue;
public string unit;
public string instructions;
public string prerequisites;
}
public class Root
{
public kkkk kk;
}
public class kkkk
{
public string preset;
public testSteps TestSteps;
}
public class testSteps
{
public CM011 CM011;
}
You could use reflection to loop through the names and the values. If you just need the items under TestSteps, this should work. If you need a full hierarchy, that is a bit more involved. Here is an example below and the fiddle to it:
using System;
using System.Reflection;
public class Program
{
public static void Main()
{
var record = new Root()
{
Foo = "foo",
Bar = "bar"
};
PropertyInfo[] rootProperties = typeof(Record).GetProperties();
foreach (PropertyInfo property in rootProperties)
{
var value = property.GetValue(record);
Console.WriteLine(property.Name + " - " + value);
}
}
}
public class Root
{
public string Foo {get;set;}
public string Bar {get;set;}
}
Making a class to deserialize to is generally done to avoid the need to loop through all the properties. You've defined all the properties in the class, so you can just use them. It's a lot of overhead to use reflection to put all the values into a class, then again using reflection to pull them back out. That's why Newtonsoft has JToken/JObject/JArray classes.
using Newtonsoft.Json.Linq;
...
// parse your JSON
var jo = JObject.Parse(jsonString);
// go through all properties
// just for an example, I put them all in a dictionary
var dict = new Dictionary<String, JToken>()
foreach( JProperty p in jo.Properties() ) {
dict.Add(p.Name, p.Value)
}
Now, each Value is a JToken, which could actually be another JObject, or a JArray or just a simple token. You can check JToken.Type to see what type the property really has, and do something logical accordingly.
i have json object which will be same in all cases and i have list of string it may vary in combination of casing.
all i want is for every string in list remove property from Json object ignoring caseing.
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
public class Program
{
public static void Main()
{
List<string> list= new List<string>();
list.Add("_iD");//this can be _ID or _Id any casing combination
list.Add("_NewId");//same as above
JObject abc = new JObject(
new JProperty("_id", "100047"),
new JProperty("_newId", "100048"));//no change in object
foreach(string s in list){
abc.Remove(s); //this code doesn't ignore casing. please suggest.
}
}
}
expected o/p: JObject abc should be empty.
as string doesnot match in casing it doesn't remove any property from above json object.
foreach(var p in abc.Properties.Where(p => list.Contains(p.Name, StringComparer.OrdinalIgnoreCase)).ToList())
{
abc.Remove(p.Name);
}
You'll need to query first and there are a lot of options here, simplest and closer to what you have already of what I can think right now is following:
foreach (string s in list)
{
var property = abc.Property(s, StringComparison.InvariantCultureIgnoreCase);
if (property != null)
{
abc.Remove(property.Name);
}
}
I know this is an old chestnut but I want to do this without importing newton-soft or json.net
I know this should work
this is the json :
{ "do": "Thing", "with": "abc" }
literally that's it. I need to get this into c# land
this is what I have so far
var json = wc.DownloadString("url");
Console.WriteLine("GOT >> " + json); //says GOT >> { "do": "Thing", "with": "abc" }
var sJson = new JavaScriptSerializer();
var data = sJson.Deserialize<Dictionary<string, string>[]>(json); //crashes with No parameterless constructor defined for type of 'System.Collections.Generic.Dictionary
what is the leanest least bloated way possible way that I can get data["do"] and data["with"] from my single line json? It will only ever return one thing ... if I have to string walk it I will but it shouldn't be this hard
You can create a backing class for the data
public class Data {
public string do { get; set; }
public string with { get; set; }
}
and simply desrialize to that
var data = sJson.Deserialize<Data>(json);
If the provided data is in fact an array then update the generic return type accordingly
There's no array in your JSON, just a simple object so it can be deserialized to a single Dictionary instance. Simply change Dictionary<string, string>[] to Dictionary<string, string>. Like this:
var data = sJson.Deserialize<Dictionary<string, string>>(json);
You can then access your values like this:
data["do"] // returns "Thing"
data["with"] // returns "abc"
The array is the problem. Try this (Try it Online!):
var json = "{ \"do\": \"Thing\", \"with\": \"abc\" }";
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(data["do"]);
Console.WriteLine(data["with"]);
output
Thing
abc
Note that I am using Json.NET here as written in the documentation:
Json.NET should be used for serialization and deserialization. Provides serialization and deserialization functionality for AJAX-enabled applications.
source
You can use Regex :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input = "{ \"do\": \"Thing\", \"with\": \"abc\" }";
string pattern = "\"(?'key'[^\"]+)\":\\s+\"(?'value'[^\"]+)";
MatchCollection matches = Regex.Matches(input, pattern);
Dictionary<string, string> dict = matches.Cast<Match>()
.GroupBy(x => x.Groups["key"].Value, y => y.Groups["value"].Value)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
I am trying to get value of label from following string.
I have a string in this format.
var string = "[{\"key\":\"182\",\"label\":\"testinstitution\"}]"
dynamic dict = new JavaScriptSerializer().Deserialize<dynamic>(string);
string inst = dict["label"]; //This is not working
I am getting dict in form of key value pair object but I am not able to get value of label. I cannot use JSON.NET.
To retrieve value of label from your string use string inst = dict[0]["label"];.
Explanation
The reason why you need additional [0] is because deserialization returns array of key value pairs. First object from that array will go to index [0], second object from array to index [1] an so on. Your string has array of only one object. Here is an example of when you have two objects, where second object has another object inside of it, in which case you would have to write dict[1]["foo"]["two"] to get to desired value:
var myString = #"
[
{
'one': '1'
},
{
'foo':
{
'two': '2'
}
}
]";
dynamic dict = new JavaScriptSerializer().Deserialize<dynamic>(myString);
string inst = dict[1]["foo"]["two"];
Additional FYI
If you know structure of your data consider using strong types (as suggested in one of the comments). Here is example of how you would do it:
public class Data
{
public string key { get; set; }
public string label { get; set; }
}
class Program
{
static void Main(string[] args)
{
var myString = #"
[{
'key': 182,
'label': 'testinstitution'
}]";
List<Data> dict = new JavaScriptSerializer().Deserialize<List<Data>>(myString);
foreach (var d in dict)
Console.WriteLine(d.key + " " + d.label);
Console.ReadKey();
}
}
Note that properties key and value in your Data object much match names of those in your array of objects exactly.
this is the JSON I have
{
"productNum":6,
"01":
{"US_7":"pna886377847444","US_7_5":"pna886377847529","US_8":"pna886377847604","US_8_5":"pna886377847666","US_9":"pna886377847741","US_9_5":"pna886377847826","US_10":"pna886377847895","US_10_5":"pna886377847987","US_11":"pna886377848069","US_11_5":"pna886377848144","US_12":"pna886377848229","US_13":"pna886377848328","US_14":"pna886377848427"},
"02":
{"US_7":"pna886377849103","US_7_5":"pna886377849202","US_8":"pna886377849295","US_8_5":"pna886377849394","US_9":"pna886377849493","US_9_5":"pna886377849592","US_10":"pna886377849660","US_10_5":"pna886377849745","US_11":"pna886377849820","US_11_5":"pna886377849905","US_12":"pna886377849981","US_13":"pna886377850086","US_14":"pna886377850185"}
}
A better view of the data:
What class should I describe to parse it ?
Looks like you can't turn this into a class because 02 is not a valid property name.
You can try using JObject that comes with Json.Net. It acts much like a Dictionary:
Here's a sample:
[Test]
public void Parse()
{
const string src = #"{
""productNum"":6,
""01"":
{""US_7"":""pna886377847444"",""US_7_5"":""pna886377847529"",""US_8"":""pna886377847604"",""US_8_5"":""pna886377847666"",""US_9"":""pna886377847741"",""US_9_5"":""p na886377847826"",""US_10"":""pna886377847895"",""US_10_5"":""pna886377847987"",""US_11"":""pna886377848069"",""US_11_5"":""pna886377848144"",""US_12"":""pna88637784 8229"",""US_13"":""pna886377848328"",""US_14"":""pna886377848427""},
""02"":
{""US_7"":""pna886377849103"",""US_7_5"":""pna886377849202"",""US_8"":""pna886377849295"",""US_8_5"":""pna886377849394"",""US_9"":""pna886377849493"",""US_9_5"":""p na886377849592"",""US_10"":""pna886377849660"",""US_10_5"":""pna886377849745"",""US_11"":""pna886377849820"",""US_11_5"":""pna886377849905"",""US_12"":""pna88637784 9981"",""US_13"":""pna886377850086"",""US_14"":""pna886377850185""}
}";
// filtering out the "productNum:6"
var dest =
JsonConvert.DeserializeObject<IDictionary<string, object>>(src)
.Where(x => x.Value.GetType() == typeof (JObject));
foreach (var item in dest)
{
var obj = (JObject) item.Value;
Console.WriteLine(item.Key);
foreach (var d in obj)
{
Console.WriteLine("{0}: {1}", d.Key, d.Value);
}
}
}
Use json.Net - http://james.newtonking.com/pages/json-net.aspx
Beyond that your question is too general. There are many ways you can go about doing it. The simple approach is to make a class, call it Product it's definition would something like;
public class Product
{
int productNum;
InnerData one;
InnerData two;
}
Before you serialize, rewrite the 01 and 02 to be one and two. InnerData should look something like;
public class InnerData
{
string US_1;
string US_2;
// rest of US_x fields
}
Then you can use the deserialize method - http://james.newtonking.com/projects/json/help/index.html?topic=html/SerializingJSON.htm
Product prod1 = jsonConvert.Deserialize<Product>(jsonString);
Found a solution myself:
string jString = File.ReadAllText(#"C:\_junk\funkyJSON.txt");
var deserializer = new JavaScriptSerializer();
var result = deserializer.DeserializeObject(jString);
var mapDyn = result as Dictionary<string, object>;
var valueSize = ((Dictionary<string, object>)mapDyn["01"])["US_7"].ToString();
Using .Net 4.5's DataContractSerializer, you can give a JSON element any variable name, while specifying its actual name with the "Name" attribute.
So your class could look like:
[DataContract]
public class MyData
{
[DataMember(Name="01")]
string Var1;
...
}
http://msdn.microsoft.com/en-us/library/bb412179.aspx