Deserialize JSON object with unknown name - c#

I have json like this
{
"result": "success",
"response_code": 200,
"message": "",
"collection": {
"<channel_id>": {
"<category_id>": {
"id_category": "<category_id>",
"name": "<category>",
"date_created": "<date_tagged>"
},
"<category_id>": {
"id_category": "<category_id>",
"name": "<category>",
"date_created": "<date_tagged>"
}
}
}
}
which channel_id and category_id is not a fixed name. How do I can deserialize it on C#?

Assuming everything else is pretty much fixed, you might try to model this along these lines:
public class MyJsonClass
{
public String Result { get; set; }
public int Response_Code { get; set; }
public String Message { get; set; }
public Dictionary<String, Dictionary<String, JsonCategoryDescription>>
Collection { get; set; }
}
public class JsonCategoryDescription
{
public String Id_Category { get; set; }
public String Name { get; set; }
public String Date_Created { get; set; }
}
Then you deserialize it as follows (System.Web.Script.Serialization namespace):
var result = new JavaScriptSerializer().Deserialize<MyJsonClass>(myJsonString);
and you can access specific fields, like so:
result.Collection[SOME_CHANNEL_ID][SOME_CATEGORY_ID].Name = "XXX";

If you use Dynamic instead of a static type you can have a variable schema of your JSON file. Here is a working console program:
class Program
{
static void Main(string[] args)
{
var json = File.ReadAllText("file.json");
dynamic obj = JObject.Parse(json);
Console.WriteLine(obj.collection.channel_id);
}
}

Related

Parse (Deserialize) JSON with dynamic keys (C#)

I want to parse the JSON on the bottom. Till now I always have the static key for the variables, but in this example, the keys are always changing. Here the "58e7a898dae4c" and "591ab00722c9f" could have any value and change constantly. How can I get the value of the elements of the set to be able to reach the PreviewName value?
{
"key": "gun",
"objects": [
{
"name": "AK47",
"sets": {
"58e7a898dae4c": {
"set_id": "58e75660719a9f513d807c3a",
"preview": {
"resource": {
"preview_name": "preview.040914"
}
}
},
"591ab00722c9f": {
"set_id": "58eba618719a9fa36f881403",
"preview": {
"resource": {
"preview_name": "preview.81a54c"
}
}
}
}
}
]
}
public class Object
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("sets")]
public Dictionary<string, Set> Sets { get; set; }
}
public class Set
{
[JsonProperty("set_id")]
public string SetId { get; set; }
[JsonProperty("preview")]
public Preview Preview { get; set; }
}
public class Preview
{
[JsonProperty("resource")]
public ResourcePreview Resource { get; set; }
}
public class ResourcePreview
{
[JsonProperty("preview_name")]
public string PreviewName { get; set; }
}
var root = JsonConvert.DeserializeObject<RootObject>(json);
string previewName1 = root.Objects[0].Sets["58e7a898dae4c"].Preview.Resource.PreviewName;
string previewName2 = root.Objects[0].Sets["591ab00722c9f"].Preview.Resource.PreviewName;
you don't need to deserialize, you can parse
var jsonParsed=JObject.Parse(json);
string[] previewNames= ((JArray)jsonParsed["objects"])
.Select(v => ((JObject)v["sets"]))
.Select(i=>i.Properties().Select(y=> y.Value["preview"]["resource"])).First()
.Select(i=> (string) ((JObject)i)["preview_name"]).ToArray();
result
preview.040914
preview.81a54c

Deserialize post request

im trying to deserilize this code on Windows Forms with C#, and i need to insert on a table the "response" foreach register, but i dont know how to access to every response section.
[
{
"error": false,
"code_error": 0,
"error_message": null,
"response": {
"cp": "83240",
"asentamiento": "Fuentes Del Mezquital",
"tipo_asentamiento": "Colonia",
"municipio": "Hermosillo",
"estado": "Sonora",
"ciudad": "Hermosillo",
"pais": "México"
}
},
{
"error": false,
"code_error": 0,
"error_message": null,
"response": {
"cp": "83240",
"asentamiento": "Las Quintas",
"tipo_asentamiento": "Colonia",
"municipio": "Hermosillo",
"estado": "Sonora",
"ciudad": "Hermosillo",
"pais": "México"
}
},
]
the provider gave me this code, and if you see in the code below only open the console in case that an error occours. but in the else clausule i need to access in the response to get the params for each register.
{
class Program
{
static void Main(string[] args)
{
string endpoint_sepomex = "http://api-sepomex.hckdrk.mx/query/";
string method_sepomex = 'info_cp/';
string variable_string = '?type=simplified';
string url = endpoint_sepomex + method_sepomex + variable_string;
var response = new WebClient().DownloadString(url);
dynamic json = JsonConvert.DeserializeObject(response);
foreach(var i in json)
{
if(i.error)
{
Console.WriteLine("Algo salio mal");
}
else
{
Console.WriteLine("Todo salio bien");
}
}
}
}
}
You would want to create a model. You can use a site like Json2CSharp to help with the process:
public class Response {
[JsonProperty("cp")]
public string Cp { get; set; }
[JsonProperty("asentamiento")]
public string Asentamiento { get; set; }
[JsonProperty("tipo_asentamiento")]
public string TipoAsentamiento { get; set; }
[JsonProperty("municipio")]
public string Municipio { get; set; }
[JsonProperty("estado")]
public string Estado { get; set; }
[JsonProperty("ciudad")]
public string Ciudad { get; set; }
[JsonProperty("pais")]
public string Pais { get; set; }
}
public class BaseResponse {
[JsonProperty("error")]
public bool Error { get; set; }
[JsonProperty("code_error")]
public int CodeError { get; set; }
[JsonProperty("error_message")]
public object ErrorMessage { get; set; }
[JsonProperty("response")]
public Response Response { get; set; }
}
Then you can deserialize like so:
var obj = JsonConvert.DeserializeObject<List<BaseResponse>>(response);

How can I convert a json string to a json array using Newtonsoft?

I am using this code to read a json file firstSession.json and display it on a label.
var assembly = typeof(ScenarioPage).GetTypeInfo().Assembly;
string jsonFileName = "firstSession.json";
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new StreamReader(stream))
{
var json = reader.ReadToEnd(); //json string
var data = JsonConvert.DeserializeObject<SessionModel>(json);
foreach (SessionModel scenario in data)
{
scenarioName.Text = scenario.title;
break;
}
scenarioName.Text = data.title; // scenarioName is the name of the label
}
SessionModel.cs looks like:
public class SessionModel : IEnumerable
{
public int block { get; set; }
public string name { get; set; }
public string title { get; set; }
public int numberMissing { get; set; }
public string word1 { get; set; }
public string word2 { get; set; }
public string statement1 { get; set; }
public string statement2 { get; set; }
public string question { get; set; }
public string positive { get; set; } // positive answer (yes or no)
public string negative { get; set; } // negative answer (yes or no)
public string answer { get; set; } // positive or negative
public string type { get; set; }
public string format { get; set; }
public string immersion { get; set; }
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
The beginning of my json is:
{
"firstSession": [
{
"block": 1,
"name": "mark",
"title": "mark's house",
"numberMissing": 1,
"word1": "distracted",
"word2": "None",
"statement1": "string 1",
"statement2": "None",
"question": "question",
"positive": "No",
"negative": "Yes",
"answer": "Positive",
"type": "Social",
"format": "Visual",
"immersion": "picture"
},
I am getting a Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object into type "MyProject.SessionModel" because the type requires a JSON array to deserialize correctly. To fix this error either change the JSON to a JSON array or change the deserialized type so that it is a normal .NET type that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'firstSession', line 2, position 17.
How can I convert the json string to a json array? Or make one of the other modifications the debugger suggests?
you need to create a wrapper class (json2csharp.com will help you do this)
public class Root {
public List<SessionModel> firstSession { get; set; }
}
then
var data = JsonConvert.DeserializeObject<Root>(json);
data.firstSession will be a List<SessionModel>
Create a new Class and have firstSession as List of SessionModel.
public class Sessions
{
public List<SessionModel> firstSession { get; set; }
}
Remove IEnumerable from the SessionModel
public class SessionModel
{
public int block { get; set; }
public string name { get; set; }
public string title { get; set; }
}
Change thedeserialization part as follows
var data = JsonConvert.DeserializeObject(line);
foreach (SessionModel scenario in data.firstSession)
{
//Here you can get each sessionModel object
Console.WriteLine(scenario.answer);
}

How to fix cannot deserialize JSON, confused with the key "1" , "2"

I am confuse with the numbered(the key) newslist (array)
The json string is valid, in nodeJS it managed to output the values that i need.
JSON STRING as is
{
"newsalert": [{
"newslist": {
"1": {
"newsid": "4321",
"headline": "Great White Shark Found",
"newscode": "GWS",
"newstime": "10:04:32"
},
"2": {
"newsid": "8031",
"headline": "Polar Bear Escaped",
"newscode": "PBE",
"newstime": "09:28:03"
}
}
}]
}
C# Code
class MainNews {
public Dictionary<string, newslist[]> newsalert { get; set; }
}
class newslist {
public int newsid { get; set; }
public string headline{ get; set; }
public string newscode { get; set; }
public string newstime { get; set; }
}
static void ShowObject(MainNews obj) {
foreach (var item in obj.news.Values.ElementAt(0)) {
MessageBox.Show(item.headline);
}
}
private void BtnTest_Click(object sender, RoutedEventArgs e) {
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
var xnews = JsonConvert.DeserializeObject<MainNews>(jsonstring);
ShowObject(xnews);
}
Error
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array because the type requires a JSON object
You are missing a step betwwen your root and the Dictionary.
newsalert is a collection on a object with a property name newslist.
That this is your dictionary.
public class MainNews
{
public List<NewAlert> newsalert { get; set; }
}
public class NewAlert
{
public Dictionary<int, NewItem> newslist { get; set; }
}
public class NewItem
{
public string newsid { get; set; }
public string headline { get; set; }
public string newscode { get; set; }
public string newstime { get; set; }
}
You can simply :
string input = #"{
""newsalert"": [{
""newslist"": {
""1"": {
""newsid"": ""4321"",
""headline"": ""Great White Shark Found"",
""newscode"": ""GWS"",
""newstime"": ""10:04:32""
},
""2"": {
""newsid"": ""8031"",
""headline"": ""Polar Bear Escaped"",
""newscode"": ""PBE"",
""newstime"": ""09:28:03""
}
}
}]
}";
var result = JsonConvert.DeserializeObject<MainNews>(input);
result.newsalert.SelectMany(x=> x.newslist.Values).Dump();
Live Demo: https://dotnetfiddle.net/Ar5ocP

decode string from web to c# object - look the content value is incremented depending on count

Im having with the content. it is auto increment.
the result is static but the content is dynamic.
I'm using a hardcoded array in catching the return string from the web. Can anyone json decoder in converting the returned string to c# object
This is the returned string from web:
{
"result":{
"count":"3"
},
"content_1":{
"message_id":"23",
"originator":"09973206870",
"message":"Hello",
"timestamp":"2016-09-14 13:59:47"
},
"content_2":{
"message_id":"24",
"originator":"09973206870",
"message":"Test again.",
"timestamp":"2016-09-14 14:49:14"
},
"content_3":{
"message_id":"25",
"originator":"09973206870",
"message":"Another message",
"timestamp":"2016-09-14 14:49:20"
}
}
On site json2csharp.com you can generate classes for JSON data.
Generated classes needs some improvements and can look like:
public class Result
{
public string count { get; set; }
}
public class Content
{
public string message_id { get; set; }
public string originator { get; set; }
public string message { get; set; }
public string timestamp { get; set; }
}
public class RootObject
{
public Result result { get; set; }
public Content content_1 { get; set; }
public Content content_2 { get; set; }
public Content content_3 { get; set; }
}
And using JSON.NET you can deserialize it:
public class Program
{
static public void Main()
{
string json = "{ \"result\":{ \"count\":\"3\" }, \"content_1\":{ \"message_id\":\"23\", \"originator\":\"09973206870\", \"message\":\"Hello\", \"timestamp\":\"2016-09-14 13:59:47\" }, \"content_2\":{ \"message_id\":\"24\", \"originator\":\"09973206870\", \"message\":\"Test again.\", \"timestamp\":\"2016-09-14 14:49:14\" }, \"content_3\":{ \"message_id\":\"25\", \"originator\":\"09973206870\", \"message\":\"Another message\", \"timestamp\":\"2016-09-14 14:49:20\" } }";
RootObject ro = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(ro.content_1.message_id);
Console.WriteLine(ro.content_2.message_id);
}
}

Categories