C# - How to parse json - c#

I have a json string as following
string json = "{\"Method\":\"LOGIN\",\"Skill\":{\"1\":\"SKILL-1\",\"2\":\"SKILL-2\"}}";
I am using JavaScriptSerializer to parse json
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
var dict = oSerializer.Deserialize<Dictionary<string,object>>(json);
I am getting Method = LOGIN using following line
MessageBox.Show("Method = "+dict["Method"].ToString());
But how to get Skill in a loop. like
Skill
1 = SKILL-1
2 = SKILL-2

The value mapping to your Skill key is actually another Dictionary<string, object>. You can iterate it by casting the object:
string json = "{\"Method\":\"LOGIN\",\"Skill\":{\"1\":\"SKILL-1\",\"2\":\"SKILL-2\"}}";
var oSerializer = new JavaScriptSerializer();
var dict = oSerializer.Deserialize<Dictionary<string,object>>(json);
var innerDict = dict["Skill"] as Dictionary<string, object>;
if (innerDict != null)
{
foreach (var kvp in innerDict)
{
Console.WriteLine ("{0} = {1}", kvp.Key, kvp.Value);
}
}
Or, the alternative would be to map your object into a proper class and deserialize to it instead of a generic Dictionary<string, object>.

Suppose you have following class
public class Data
{
public string Method { get; set; }
public Skills Skill { get; set; }
// If you don't want to use Skills class then you can use this
//public Dictionary<int, string> Skills { get; set; }
}
public class Skills
{
public int Id { get; set; }
public string Skill { get; set; }
}
So you can Deserialize json into Data Object like this
Data deserializedData = JsonConvert.DeserializeObject<Data>(json);

You should declare your own class:
public class YourClassName
{
public string Method { get; set; }
public Dictionary<int, string> Skill { get; set; }
}
and deserialize the Json string like this:
var obj = oSerializer.Deserialize<YourClassName>(json);

Related

How to do a projection on json string

How to query some json to select a specific property?
EX: If I have Json obj like this :
[
{
"grd_symbol":"A+",
"count":21.23,
"code":4,
"name":"X",
"batch_no":760
},
{
"grd_symbol":"A ",
"count":11.93,
"code":4,
"name":"X",
"batch_no":760
},
{
"grd_symbol":"A-",
"count":8.49,
"code":4,
"name":"X",
"batch_no":760
}
]
This's the output of :
string JsonObj = Converter.ConvertDataTabletoString(DT);
public static string ConvertDataTabletoString(DataTable dt)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
Dictionary<string, object> row;
foreach (DataRow dr in dt.Rows)
{
row = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
row.Add(col.ColumnName, dr[col]);
}
rows.Add(row);
}
return serializer.Serialize(rows);
}
Now I want to get the count only,The result will be like this:
[21.23,11.93,8.49]
Take a look at Newtonsoft.JSON.
Using this, we can create an object to match the json string:
public class MyCustomObject
{
[JsonProperty("grd_symbol")] public string GridSymbol {get; set;}
[JsonProperty("count")] public double Count {get; set;}
[JsonProperty("code")] public int Code {get; set;}
[JsonProperty("name")] public string Name {get; set;}
[JsonProperty("batch_no")] public int BatchNumber {get; set;}
}
Then you can deserialize your json using the library mentioned above:
var myData = JsonConvert.DeserializeObject<MyCustomObject[]>(jsonString);
And then, since you want an array of the counts, you can use LINQ to get them using Select:
var countArray = myData.Select(x => x.Count);
And of course, if you want to output this as a string, you can just serialize it again:
var countString = JsonConvert.SerializeObject(countArray);
You don't even have to to deserialise all property to select just one you can simple omit the unwanted one in the calss definition so they will be ignored.
Using :
public class SimplifyRootObject
{
public double count { get; set; }
}
Instead of :
public class RootObject
{
public string grd_symbol { get; set; }
public double count { get; set; }
public int code { get; set; }
public string name { get; set; }
public int batch_no { get; set; }
}
Then a simple string.Join() to add the comma and there you are.
$"[{string.Join("_separator_", myListOfDouble)}]"
MCVE:
public static void Main(string[] args)
{
string input = #"[
{
""grd_symbol"":""A+"",
""count"":21.23,
""code"":4,
""name"":""X"",
""batch_no"":760
},
{
""grd_symbol"":""A "",
""count"":11.93,
""code"":4,
""name"":""X"",
""batch_no"":760
},
{
""grd_symbol"":""A-"",
""count"":8.49,
""code"":4,
""name"":""X"",
""batch_no"":760
}
]";
// Deserialize All, select the wanted.
var m = JsonConvert.DeserializeObject<List<RootObject>>(input);
var result = m.Select(x=> x.count);
Console.WriteLine("["+string.Join(", ", result)+"]");
// Deserialize only one, select it.
var m2 = JsonConvert.DeserializeObject<List<SimplifyRootObject>>(input);
var result2 = m.Select(x=> x.count);
Console.WriteLine("["+string.Join(", ", result2)+"]");
}
}
https://rextester.com/PFJZN10272;
The label of your topic is "how to do a projection on json string" and you're telling us that you already have a DataTable that you want to convert into a string.
The code you gave us though means "I want to serialize my datatable into a JSON string".
In the end, what do you even need ? An array of string ? a string ? a json object ?
If it's a string, i would suggest you to override the ToString() method of DataTable to get the format you want i.e [number1, number2, number3] by fetching the datatable and returning a STRING and not a JSON.
Edit. #ThePerplexedOne has answered the question, i think.

How to find a specific value in an IDictionary<string, object>?

This IDictionary<string, object> contains user data I'm logging into mongodb. The issue is the TValue is a complex object. The TKey is simply the class name.
For example:
public class UserData
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Admin NewAdmin { get; set; }
}
public class Admin
{
public string UserName { get; set; }
public string Password { get; set; }
}
Currently, I'm trying to iterate through the Dictionary and compare types but to no avail. Is there a better way of doing this or am I missing the mark?
var argList = new List<object>();
foreach(KeyValuePair<string, object> kvp in context.ActionArguments)
{
dynamic v = kvp.Value;
//..compare types...
}
Just use OfType<>(). You don't even need the key.
public static void Main()
{
var d = new Dictionary<string,object>
{
{ "string", "Foo" },
{ "int", 123 },
{ "MyComplexType", new MyComplexType { Text = "Bar" } }
};
var s = d.Values.OfType<string>().Single();
var i = d.Values.OfType<int>().Single();
var o = d.Values.OfType<MyComplexType>().Single();
Console.WriteLine(s);
Console.WriteLine(i);
Console.WriteLine(o.Text);
}
Output:
Foo
123
Bar
Link to Fiddle

How to itrate JSON object?

I trying to get the id and email list from the JSON. How can i achieve this?
My JSON string is
{
"name":"name1",
"username":"name1",
"id":505,
"state":"active",
"email":"name1#mail.com",
},
{
"name":"name2",
"username":"name2",
"id":504,
"state":"active",
"email":"name2#mail.com",
}
My code is
Dictionary<string, string> engineers = new Dictionary<string, string>();
using (StreamReader r = new StreamReader(#"D:\project\Gitlap\EngineerEmail\jsonlist5.json"))
{
using (JsonTextReader reader = new JsonTextReader(r))
{
JObject o2 = (JObject)JToken.ReadFrom(reader);
string id = o2["id"].ToString();
string email = o2["email"].ToString();
engineers.Add(email, id);
}
}
class UserItems
{
public string id { get; set; }
public string email { get; set; }
}
I can able to get the first person`s mail ID and ID details. I need to iterate this JSON and get all the mail ID and ID.
I don`t know that how to iterate this JSON. I tried some method from the internet but that was not succeeded.
How can I do?
First thing is your JSON input is not valid json, you need to fix it. There are two issues in it. Its not collection of json objects and comma is missing between two objects.
Valid json should look like below.
[{
"name":"name1",
"username":"name1",
"id":505,
"state":"active",
"email":"name1#mail.com",
},
{
"name":"name2",
"username":"name2",
"id":504,
"state":"active",
"email":"name2#mail.com",
}]
Now define a c# class representing your json object.
public class User
{
public string name { get; set; }
public string username { get; set; }
public int id { get; set; }
public string state { get; set; }
public string email { get; set; }
}
Use JSON.Net library to deserialize it as shown below.
private void button1_Click(object sender, EventArgs e)
{
if(File.Exists("json1.json"))
{
string inputJSON = File.ReadAllText("json1.json");
if(!string.IsNullOrWhiteSpace(inputJSON))
{
var userList = JsonConvert.DeserializeObject<List<User>>(inputJSON);
}
}
}
JObject o2 = (JObject)JToken.ReadFrom(reader);
foreach(var obj in o2)
{
string id = obj["id"].ToString();
string Email= obj["Email"].ToString();
engineers.Add(email, id);
}
I would recommend using the Json.NET NuGet package to accomplish this.
Firstly, create a model to represent your JSON data. Typically I would capitalize the first letter of the property names here, but to keep it consistent with the JSON, they are lower case.
public class UserData
{
public string name { get; set; }
public string username { get; set; }
public int id { get; set; }
public string state { get; set; }
public string email { get; set; }
}
You will need to add a using for Json.NET
using Newtonsoft.Json;
Finally, you can load, and deserialize your data into a strongly typed list, which you can then use to populate your engineers dictionary.
string datapath = #"D:\project\Gitlap\EngineerEmail\jsonlist5.json";
Dictionary<string, string> engineers = new Dictionary<string, string>();
List<UserData> data = new List<UserData>();
using (StreamReader r = new StreamReader(datapath))
{
string json = r.ReadToEnd();
data = JsonConvert.DeserializeObject<List<UserData>>(json);
data.ForEach(engineer => engineers.Add(engineer.email, engineer.id.ToString()));
}
As mentioned in another answer, your JSON is also badly formed. This will need correcting before it will deserialize correctly. We just need to add a comma to separate the two objects, and wrap them both in a JSON array, with []
[
{
"name":"name1",
"username":"name1",
"id":505,
"state":"active",
"email":"name1#mail.com"
},
{
"name":"name2",
"username":"name2",
"id":504,
"state":"active",
"email":"name2#mail.com"
}
]
Improvements
As your Id field is an integer, it would be better to change your dictionary from
Dictionary<string, string> engineers = new Dictionary<string, string>();
into
Dictionary<string, int> engineers = new Dictionary<int, string>();
You will then be able to simplify your ForEach query slightly. The ForEach can also be moved outside of the using() block.
data.ForEach(engineer =>
engineers.Add(engineer.email, engineer.id));
Improved solution
This includes the improvements above, I've used var for brevity.
var datapath = #"D:\project\Gitlap\EngineerEmail\jsonlist5.json";
var engineers = new Dictionary<string, int>();
var data = new List<UserData>();
using (var r = new StreamReader(datapath))
{
var json = r.ReadToEnd();
data = JsonConvert.DeserializeObject<List<UserData>>(json);
}
data.ForEach(engineer =>
engineers.Add(engineer.email, engineer.id));
try to create class that represent the data in json object for example
Class obj
{
public int Id { get ; set; }
public string email { get ; set; }
public string username { get ; set; }
public string state { get ; set; }
public string email { get ; set; }
}
then
using System.Web.Script.Serialization;
var js = new JavaScriptSerializer();
List<obj> list = js.Deserialize<List<obj>>(jsonString);
after that you can access all list items id and email by using foreach

Nested Json array in MVC Controller

Pretty silly question to ask. but could not figure it out .
In a C# MVC Controller action , I need to model a Json Array for testing purposes.
But this shows me compilation errors instead of being a valid Json:
var result = {
"controllerId": "controller1",
"controllerName": "ControllerOne"
};
But this is perfectly valid :
var scheduleResult = new[]
{
new { scheduleId = "schedule1",scheduleName = "scheduleOne"},
new { scheduleId = "schedule2",scheduleName = "scheduleTwo"}
};
Why so ?
Also how to write a nested Json array :
I tried :
var scheduleResult = new[]
{
new { scheduleId = "schedule1",scheduleName = "scheduleOne",new[]{ new {doorId="Door1",doorName="DoorOne"}, new { doorId = "Door2", doorName = "DoorTwo" } } },
new { scheduleId = "schedule2",scheduleName = "scheduleTwo"}
};
But it shows errors in syntax. What to do ?
I Need to have nested array within each element of that array .
Thanks in advance.
Well, C# does not support the way you wrote. You can't just type in JSON in C# and expect it to work unfortunately. You can try like that with anonymous type:
var result = new
{
controllerId = "controller1",
controllerName = "ControllerOne",
myArray = new []
{
"a",
"b"
}
};
This is converted to JSON no problem if you return it as a result of API call.
The nested arrays you are talking about don't work because you need to give them a name, you can't have array property without a name. See example above.
Why don't you use Dictionary<TKey, TValue> with Newtonsoft.Json?
Simple json:
IDictionary<string, string> obj = new Dictionary<string, string>();
obj.Add("controllerId", "controller1");
obj.Add("controllerName", "ControllerOne");
// {"controllerId":"controller1","controllerName":"ControllerOne"}
string json = JsonConvert.SerializeObject(obj);
Nested json:
IList<string> obj = new List<string>();
IDictionary<string, string> first = new Dictionary<string, string>();
first.Add("scheduleId ", "schedule1");
first.Add("scheduleName", "scheduleOne");
IDictionary<string, string> second = new Dictionary<string, string>();
second.Add("scheduleId ", "schedule2");
second.Add("scheduleName", "scheduleTwo");
string first_json = JsonConvert.SerializeObject(first);
string second_json = JsonConvert.SerializeObject(second);
obj.Add(first_json);
obj.Add(second_json);
// ["{\"scheduleId \":\"schedule1\",\"scheduleName\":\"scheduleOne\"}","{\"scheduleId \":\"schedule2\",\"scheduleName\":\"scheduleTwo\"}"]
string json = JsonConvert.SerializeObject(obj);
Here first of all we should create model class with the same pattern of our return type
public class ScheduleModel
{
public List<Schedule> ScheduleList { get; set; }
}
public class Schedule
{
public int ScheduleId { get; set; }
public string ScheduleName { get; set; }
public List<Door> DoorList { get; set; }
}
public class Door
{
public int DoorId { get; set; }
public string DoorName { get; set; }
}
Now at the controller Action create the test data
List<Door> doorList = new List<Door>();
doorList.Add(new Door{DoorId = "Door1",DoorName = "DoorOne"});
doorList.Add(new Door{DoorId = "Door2",DoorName = "DoorTwo"});
List<Schedule> scheduleList = new List<Schedule>();
scheduleList.Add(new Schedule{
ScheduleId = "schedule1",
ScheduleName = "scheduleOne",
DoorList = doorList
});
scheduleList.Add(new Schedule
{
ScheduleId = "schedule2",
ScheduleName = "scheduleTwo",
});
return Json(scheduleList, JsonRequestBehavior.AllowGet);
If this answer benefits you please mark as an answer.

Deserialize JSON into string

How can I deserialize:
{
"data": [
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
}
to
class RawData
{
public string data { get; set; }
}
So, I just want to have
[
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
as value of property data of RawData's class instance.
Using Json.Net
var obj = (JObject)JsonConvert.DeserializeObject(json);
var newJson = obj["data"].ToString();
or using built-in JavaScriptSerializer
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
var newjson = new JavaScriptSerializer().Serialize(dict["data"]);
It would have made far much more sense to deserialize this JSON structure to:
public class Forecast
{
public IEnumerable<ForecastData> Data { get; set; }
}
public class ForecastData
{
public int ForecastID { get; set; }
public string StatusForecast { get; set; }
}
which is pretty trivial with the JavaScriptSerializer class that's built into the framework:
string json = "your JSON data here";
IEnumerable<ForecastData> data = new JavaScriptSerializer()
.Deserialize<Forecast>(json)
.Data;
or if you don't want to define models you could do that:
dynamic result = new JavaScriptSerializer().DeserializeObject(json);
foreach (var item in result["data"])
{
Console.WriteLine("{0}: {1}", item["ForecastID"], item["StatusForecast"]);
}

Categories

Resources