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);
}
}
Related
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'm working in C# right now and I'm using JSON.Net to parse json strings to well, C# objects. Part of my problem is that I'm getting some strings like this:
{"name": "John"}{"name": "Joe"}
When I try to deserialize with JsonConvert.DeserializeObject<>, it throws an exception.
I'm wondering what would be the best way to split of this bigger string into smaller json strings.
I was thinking about going through the string and matching curly braces of "level 0". Does this seem like a good idea? Or is there some better method to do this?
You can use a JsonTextReader with the SupportMultipleContent flag set to true to read this non-standard JSON. Assuming you have a class Person that looks like this:
class Person
{
public string Name { get; set; }
}
You can deserialize the JSON objects like this:
string json = #"{""name"": ""John""}{""name"": ""Joe""}";
using (StringReader sr = new StringReader(json))
using (JsonTextReader reader = new JsonTextReader(sr))
{
reader.SupportMultipleContent = true;
var serializer = new JsonSerializer();
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
Person p = serializer.Deserialize<Person>(reader);
Console.WriteLine(p.Name);
}
}
}
Fiddle: https://dotnetfiddle.net/1lTU2v
I found the best way is to convert your string to an array structure:
string json = "{\"name\": \"John\"}{\"name\": \"Joe\"}";
json = json.Insert(json.Length, "]").Insert(0, "[").Replace("}{", "},{");
// json now is [{"name": "John"},{"name": "Joe"}]
List<Person> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Person>>(json);
Assuming your class name is Person :
public class Person
{
public string Name { set; get; }
}
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.
I am trying to read json from a local .json file and parse the contents using StreamReader and Json.NET. Json & my code:
contents of .json file: {"rate":50,"information":{"height":70,"ssn":43,"name":"andrew"}}
using (var sr = new StreamReader(pathToJsonFile))
{
dynamic jsonArray = JsonConvert.DeserializeObject(sr.ReadToEnd());
foreach(var item in jsonArray)
{
Console.WriteLine(item.rate);
Console.WriteLine(item.ssn);
}
}
This gives me an error on the line foreach(var item in array): Object reference not set to an instance of an object. I am guessing this is because my json is not actually an array but that is how I am trying to parse it. How can I parse this json in order to pull out fields such as rate or ssn?
NB - please do not flag this question as a duplicate of Read and parse a Json File in C#, as that is where I got my original code from.
EDIT: As has been pointed out in other answers, jsonArray is null. That explains my error but still does not answer my question. How else can I parse this json in order to extract the desired fields?
A couple things:
If you want to manually parse out the values, you should try using JObject rather than JsonConvert.DeserializeObject. The following code should work:
dynamic jsonObject = JObject.Parse("{'rate':50,'information':{'height':70,'ssn':43,'name':'andrew'}}");
Console.WriteLine(jsonObject["rate"]);
Console.WriteLine(jsonObject["information"]["ssn"]);
However, if you know how the json is structured, you should create a .net class like:
public class Person
{
public int rate {get;set;}
public Information information {get;set;}
}
public class Information
{
public int height {get;set;}
public int ssn {get;set;}
public string name {get;set;}
}
and then use:
var person = JsonConvert.DeserializeObject<Person>(thestringtodeserialize);
That way you can have a strongly typed object.
In any case, I would check for null (DeserializeObject can obviously return null):
using (var sr = new StreamReader(pathToJsonFile))
{
dynamic jsonArray = JsonConvert.DeserializeObject(sr.ReadToEnd());
if(jsonArray != null) //new check here
{
foreach(var item in jsonArray)
{
Console.WriteLine(item.rate);
Console.WriteLine(item.ssn);
}
}
I am guessing this is because my json is not actually an array
True, the returned object is dynamic, so make use of dynamic:
var json = "{\"rate\":50,\"information\":{\"height\":70,\"ssn\":43,\"name\":\"andrew\"}}";
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine("rate: {0}. ssn: {1}", obj.rate, obj.information.ssn);
See live sample here: https://dotnetfiddle.net/nQYuyX
Are you sure it's an array?
If that's the format the you expect from Json, maybe you should consider defining a class.
For example:
class SomeJsonObject
{
public int rate {get;set;}
[JsonProperty("information")] //if you want to name your property something else
public InformationObject Information {get;set;}
}
class InformationObject
{
[JsonProperty("height", NullValueHandling = NullValueHandling.Ignore)] //some other things you can do with Json
public int Height {get;set;}
public int ssn {get;set;}
public string name {get;set;}
}
This way you can just deserialize it to an object:
SomeJsonObject jsonArray = JsonConvert.DeserializeObject<SomeJsonObject>(sr.ReadToEnd());
I think your question is similar to this Deserialize JSON with C# . you can use JavaScriptSerializer
I don't get a null reference (with Json.net 6.0.3) but your code has one obvious bug:
static void Main(string[] args)
{
string s = "{'rate':50,'information':{'height':70,'ssn':43,'name':'andrew'}}".Replace('\'', '\"');
var obj = JsonConvert.DeserializeObject(s);
dynamic jsonArray = obj;
foreach (var item in jsonArray)
{
Console.WriteLine(item.rate);
Console.WriteLine(item.ssn);
}
}
The bug is Console.WriteLine(item.rate) will throw.
Your 'array' jsonArray is not actually an array, it is a dictionary!
Therefore, item=the first Key-Value-pair in the dictionary, = {"rate":50}.
You can prevent the code from throwing by getting rid of your foreach loop.
i would fire up nuget and get the JSON.net package
https://www.nuget.org/packages/Newtonsoft.Json/
http://james.newtonking.com/json
it is well documented and can save you a tonne of work.
see also http://json2csharp.com/
EDIT: you are already using this
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