Deserialize JSON in C# to array - c#

I'm having trouble doing deserialize a certain json I am collecting a website.
{
"query": {
"search": [
{
"ns": 0,
"title": "test",
"snippet": "test"
},
{
"ns": 0,
"title": "test2",
"snippet": "test2"
},
{
"ns": 0,
"title": "test3",
"snippet": "test3"
},
{
"ns": 0,
"title": "test4",
"snippet": "test4"
}
]
}
}
This is the class that I'm trying to deserialize into:
private void DesURL_Click(object sender, RoutedEventArgs e)
{
string url = #"https://pt.wikipedia.org/w/api.php.....";
var json = new WebClient().DownloadString(url);
var listaURL = JsonConvert.DeserializeObject<List<Query>>(json);
}
when trying to run the code of an error that this json should be deserialized into an array. Ai trying utiilizar JArray the method I need to do the deserialize before you can turn into array.
The goal is to convert the title and snippet to string in order to extract information from it.

Pro tip for you: Select your JSON and copy it to the clipboard. Now go to Visual Studio and on the Edit menu, Paste Special and then Paste JSON as Classes. that will give you this:
public class Rootobject
{
public Query query { get; set; }
}
public class Query
{
public Search[] search { get; set; }
}
public class Search
{
public int ns { get; set; }
public string title { get; set; }
public string snippet { get; set; }
}
And now you can deserialise like this:
var listaURL = JsonConvert.DeserializeObject<Rootobject>(json);

You need the following classes:
public class Rootobject
{
public Query query { get; set; }
}
public class Query
{
public Search[] search { get; set; }
}
public class Search
{
public int ns { get; set; }
public string title { get; set; }
public string snippet { get; set; }
}
Then you can deserialize like this:
var listUrl = JsonConvert.DeserializeObject<Rootobject>(json);

Your JSON is not an array. It contains a query object with a search property that has an array value.
So your class has to look something like this
public class ResponseDto {
public QueryDto Query {get; set;}
}
public class QueryDto {
public IEnumerable<Query> Search {get; set;}
}
var data = JsonConvert.DeserializeObject<QueryDto>(json);
var list = data.Query.Search.ToList();

Related

Working with Irregular nodes/elements in json response from an API

I have a situation while working with a JSON response from an API. To give a background, I am consuming an API from a source using a REST API using 3.5 .net framework.
Below is the part of the JSON output and I am kind of struggling to use it.
a)
"value": {
"Description": "Total Calculated things",
"2018": "5,820,456 ",
"2019": "2,957,447 "
}
The last 2 elements are dynamic, those are tend to change in API response. I was expecting the format like I have mentioned below, but at this point of given time the source provider is not able to change it as the API is used in many other different programs. And Changing the things in the source API will make other program owners to change.
b)
"value": {
"Description": "Total Calculated EQUITY AND LIABILITIES",
"YearData": [ {
"Data": "5,820,456",
"Year": "2018"
},
{
"Data": "2,957,447 ",
"Year": "2019"
} ]
}
Is there any way to overcome such thing> Any way to convert a to b?
EDIT
#Xerillio , Thanks . How can I achieve the same using below JSON format.
var json = #"
{
""entityData"": [
{
""name"": ""Statement of Comprehensive Income"",
""subattrOutput"": [
{
""name"": ""Sales"",
""subattrOutput"": [],
""value"": {
""Description"": ""Sales "",
""2018"": ""8,704,888 "",
""2019"": ""4,760,717 ""
},
""score"": ""99.5"",
""valuetype"": ""object""
},
{
""name"": ""Cost of goods sold"",
""subattrOutput"": [],
""value"": {
""Description"": ""Cost of sales "",
""2018"": ""(6,791,489) "",
""2019"": ""(3,502,785) ""
},
""score"": ""99.75"",
""valuetype"": ""object""
}
],
""value"": null,
""score"": ""98.63"",
""valuetype"": ""object""
}
]
}";
I wish this was more easy, but i just got it here:
class Program
{
static async Task Main(string[] args)
{
string json1 = #"{""value"": {""Description"": ""Total Calculated things"",""2018"": ""5,820,456 "",""2019"": ""2,957,447 ""}}";
string json2 = #"{""value"": {""Description"": ""Total Calculated EQUITY AND LIABILITIES"",""YearData"": [ {""Data"": ""5,820,456"",""Year"": ""2018""},{""Data"": ""2,957,447 "",""Year"": ""2019""} ]}}";
var obj1 = JsonConvert.DeserializeObject<ObjectResult>(json1);
var obj2 = JsonConvert.DeserializeObject<ObjectResult>(json2);
var res1 = CastObject<Result1>(obj1.Value.ToString());
var res2 = CastObject<Result2>(obj2.Value.ToString());
var invalidRes1 = CastObject<Result1>(obj2.Value.ToString());
var invalidRes2 = CastObject<Result2>(obj1.Value.ToString());
Console.WriteLine(res1);
Console.WriteLine(res2);
}
public static T CastObject<T>(string obj)
{
return !TryCastObject(obj, out T result) ? default : result;
}
public static bool TryCastObject<TOut>(string objToCast, out TOut obj)
{
try
{
obj = JsonConvert.DeserializeObject<TOut>(objToCast);
return true;
}
catch
{
obj = default;
return false;
}
}
}
public class ObjectResult
{
public object Value { get; set; }
}
public class Result1
{
[JsonProperty(PropertyName = "description")] public string Description { get; set; }
[JsonProperty(PropertyName = "2018")] public string _2018 { get; set; }
[JsonProperty(PropertyName = "2019")] public string _2019 { get; set; }
}
public class Result2
{
[JsonProperty(PropertyName = "Description")] public string Description { get; set; }
[JsonProperty(PropertyName = "YearData")] public List<YearData> YearData { get; set; }
}
public class YearData
{
[JsonProperty(PropertyName = "Data")] public string Data { get; set; }
[JsonProperty(PropertyName = "Year")] public string Year { get; set; }
}
It is A LOT of work and sincerely, as there more nodes in the json i think that using JObject is the best option, and you will have to do a deserealization in more than 1 step :(
Depending on how large the JSON structure is you could deserialize it into a Dictionary and manually map it to the proper format:
var json = #"
{
""value"": {
""Description"": ""Total Calculated things"",
""2018"": ""5,820,456 "",
""2019"": ""2,957,447 ""
}
}";
var badObj = JsonSerializer.Deserialize<BadFormat>(json);
var result = new WrapperType
{
Value = new ProperlyFormattedType()
};
foreach (var pair in badObj.Value)
{
if (pair.Key == "Description")
{
result.Value.Description = pair.Value;
}
else if (int.TryParse(pair.Key, out int _))
{
result.Value.YearData
.Add(new DatedValues
{
Year = pair.Key,
Data = pair.Value
});
}
}
// Data models...
public class BadFormat
{
[JsonPropertyName("value")]
public Dictionary<string, string> Value { get; set; }
}
public class WrapperType
{
public ProperlyFormattedType Value { get; set; }
}
public class ProperlyFormattedType
{
public string Description { get; set; }
public List<DatedValues> YearData { get; set; } = new List<DatedValues>();
}
public class DatedValues
{
public string Year { get; set; }
public string Data { get; set; }
}
See an example fiddle here.

Error while de-serializing json array [duplicate]

This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 4 years ago.
I'm trying to deserialize a Json string.
This is my code:
[System.Serializable]
public class SharedWorlds
{
public int worldId { get; set; }
public System.DateTime uploaded { get; set; }
public string username { get; set; }
public string levelName { get; set; }
public string gameVersion { get; set; }
public string description { get; set; }
public string filename { get; set; }
public string screenshot1 { get; set; }
public string screenshot2 { get; set; }
public string userTag { get; set; }
public string userURL { get; set; }
public double price { get; set; }
public int nrDownload { get; set; }
public int votes { get; set; }
}
[System.Serializable]
public class Record {
public List<SharedWorlds> record;
}
try {
SDE3D _webService = new SDE3D();
result= _webService.GetMassiveWorldsList ();
var records = JsonUtility.FromJson<Record>(result);
}
catch(System.Exception ex) {
Debug.Log (ex.Message.ToString ());
}
And this is my valid jSon (here two records, but I want to send many records per time).
[
{
"worldId": 5,
"uploaded": "/Date(1524875719000)/",
"username": "quik",
"levelName": "Station",
"gameVersion": "1.0.1",
"description": "iwoeijksf",
"filename": "0000003.dat",
"screenshot1": "0000003a.png",
"screenshot2": "0000003b.png",
"userTag": "",
"userURL": "",
"price": 0,
"nrDownload": 5,
"votes": 5
},
{
"worldId": 4,
"uploaded": "/Date(1524875659000)/",
"username": "aksio",
"levelName": "Garage",
"gameVersion": "1.0.1",
"description": "Adlkld",
"filename": "0000003.dat",
"screenshot1": "0000003a.png",
"screenshot2": "0000003b.png",
"userTag": "",
"userURL": "",
"price": 0,
"nrDownload": 4,
"votes": 4
}
]
I'm getting error:
"ArgumentException: JSON must represent an object type."
I'm pretty sure the error is in this code line:
var records = JsonUtility.FromJson<Record>(result);
How to deserialize an array of json object ?
Thanks
Because your JSON data is not a Record. It's a collection of SharedWorlds. So something like this:
var sharedWorlds = JsonUtility.FromJson<SharedWorld[]>(result);
Or perhaps:
var sharedWorlds = JsonUtility.FromJson<List<SharedWorld>>(result);
From which you could create a Record:
var record = new Record { record = sharedWorlds };
If the JSON needs to deserialize into a Record then it would need to be in the format of a Record object:
{
"record":
[
/* the rest of your JSON within the square brackets */
]
}
Then it would be a Record:
var record = JsonUtility.FromJson<Record>(result);
*Side note: Your class and variable names and the pluralizations you're using are really confusing. The semantics of which is probably not making your debugging any easier for you.
You get to script collection of object no one single object in your JSON

deserialize inconsistent json to object c#

Can someone tell me how to deserialize JSON to a C# (without using C# dynamic) object when JSON string is having dynamic array of data?
Given below JSON is having Boxes object and it can contain Array of fashion items (It can be pants, sweater, shoes,...etc)
{
"task": {
"id": 269740275,
"status": "success",
"error": null,
"date_created": "2017-02-16T10:33:41.827688Z",
"date_updated": "2017-02-16T10:33:42.417778Z",
"data": {
"width": 1062,
"boxes": {
"top-shirt": [
{
"xmin": 0.249980241060257,
"ymin": 0.1535395532846451,
"ymax": 0.476559966802597,
"xmax": 0.6146213412284851,
"proba": 0.9977585077285767
}
],
"shoe": [
{
"xmin": 0.3686676025390625,
"ymin": 0.9223044514656067,
"ymax": 0.9838011264801025,
"xmax": 0.4768480360507965,
"proba": 0.9748706817626953
}
],
"pants": [
{
"xmin": 0.3451904654502869,
"ymin": 0.4616038501262665,
"ymax": 0.909162700176239,
"xmax": 0.6047541499137878,
"proba": 0.9983627200126648
}
]
},
"height": 1503
}
}
}
You can use a dictionary to handle the dynamic part of the JSON (boxes).
Define your classes like this:
public class RootObject
{
public Task task { get; set; }
}
public class Task
{
public int id { get; set; }
public string status { get; set; }
public object error { get; set; }
public DateTime date_created { get; set; }
public DateTime date_updated { get; set; }
public Data data { get; set; }
}
public class Data
{
public int width { get; set; }
public Dictionary<string, List<Item>> boxes { get; set; }
public int height { get; set; }
}
public class Item
{
public double xmin { get; set; }
public double ymin { get; set; }
public double ymax { get; set; }
public double xmax { get; set; }
public double proba { get; set; }
}
Then deserialize like this:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
Fiddle: https://dotnetfiddle.net/Sxz8P3
Use NuGet to fetch the Newtonsoft.JSON package.
Then you can use linq-to-json to handle this kind of data object.
For example, assuming your example JSON string is stored in input,
var message = JObject.Parse(input);
var width = (int)message["task"]["data"]["width"];
var height = (int)message["task"]["data"]["height"];
Console.WriteLine(width + " " + height);
var boxes = message["task"]["data"]["boxes"];
foreach (var box in boxes.Children<JProperty>())
{
Console.WriteLine(box.Name) ;
}
This is pretty close to Javascript and works well.
I think O. Jones provided the easiest solution, using Newtonsoft, Newtonsoft is literally the best possible way to do anything with JSON in C# and without any headaches.
Here's one of the simplest examples
string json_string = #"{
Firstname: ""Jane"",
Lastname: ""Doe"",
Age: 36,
IsEmployed: true,
IsMarried: true,
Children: 4
}";
var person = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json_string);
Console.WriteLine(person.Forename);
Console.WriteLine(person.Lastname);
Console.WriteLine(person.Age);
Console.WriteLine(person.IsEmployed);
Console.WriteLine(person.IsMarried);
Console.WriteLine(person.Children);
It generates objects on the fly, no matter the structure!
I wrote a simple, easy-to-follow article here https://turmanauli.medium.com/a-complete-guide-for-serializing-json-to-dynamic-objects-on-the-fly-in-c-7ab4799f648d
about how to use Newtonsoft in your Visual Studio project.

Json parse sub-collection in c#

How can I do JSON in C# like the data below ?
{
"Aliases": [ "teddy", "freddy", "eddy", "Betty" ],
"Name":"reacher gilt",
"Address":"100 East Way",
"Age":74,
"Bars": {
"items": [
{
"Sub_Property1":"beep",
"Sub_Property2":"boop"
},
{
"Sub_Property1":"meep",
"Sub_Property2":"moop"
},
{
"Sub_Property1":"feep",
"Sub_Property2":"foop"
}
]
}
}
Actually my problem is inside the sub-collection. I saw someone did something
like this
person.Bars.Add("items",
new List<BarClass>(new[]{
new BarClass("beep","boop"),
new BarClass("meep","moop"),
new BarClass("feep","foop"),
}));
So, I have to add new BarClass("beep","boop"), but I need to do something
like this
String [] no1 = {1,2,3}
String [] no2 = {4,5,6}
person.Bars.Add("items",
new List<BarClass>(new[]{
for ()
{
new BarClass(no1[i],no2[i])
}
}));
How can i do this? Thanks and please help..
To read the JSON
The best way to read the whole JSON is to Deserialize it to a native C# object. If you do not already have the classes with your, you can create it in Visual Studio as
Copy your JSON text
Create a new empty class file in VS
Edit > Paste Special > Paste JSON As Classes
Here are the classes
public class Person
{
public string[] Aliases { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public Bars Bars { get; set; }
}
public class Bars
{
public Item[] items { get; set; }
}
public class Item
{
public string Sub_Property1 { get; set; }
public string Sub_Property2 { get; set; }
}
Now you can use some .NET JSON library to deserialize. JSON.Net aka Newtonsoft JSON is a great library. You get get it from NuGet as well.
Then it's pretty easy to get the C# object from the JSON
//using Newtonsoft.Json;
var jsonString = File.ReadAllText(#"C:\YourDirectory\person.json");
var person = JsonConvert.DeserializeObject<Person>(jsonString);
If you want to read the sub-collection only, you can rather use Linq-to-JSON to read the items directly, like this
//using Newtonsoft.Json.Linq;
var jObject = JObject.Parse(jsonString);
List<Item> details = jObject["Bars"]["items"].ToObject<List<Item>>();
To create the JSON
You first need to create the object, then Serialize to JSON
string[] subProperties1 = new string[] { "1", "2", "3" };
string[] subProperties2 = new string[] { "4", "5", "6" };
Person person = new Person { Name = "Johny", Age = 7, Address = "Earth", Aliases = new string[] { "Sony", "Monty" } };
person.Bars = new Bars {
items = subProperties1.Zip(subProperties2,
(prop1, prop2) => new Item { Sub_Property1 = prop1, Sub_Property2 = prop2 })
.ToArray() };
var json = JsonConvert.SerializeObject(person);
To create the items from your existing string arrays, I have used IEnumerable.Zip function from Linq. You can read about them here.
This is the created JSON data
{
"Aliases": [ "Sony", "Monty" ],
"Name": "Johny",
"Address": "Earth",
"Age": 7,
"Bars": {
"items": [
{
"Sub_Property1": "1",
"Sub_Property2": "4"
},
{
"Sub_Property1": "2",
"Sub_Property2": "5"
},
{
"Sub_Property1": "3",
"Sub_Property2": "6"
}
]
}
}
You should create some classes
public class Person
{
public string Name {get;set;}
public string Address{get;set;}
public int Age {get;set;}
public Header {get;set;}
}
public class Header
{
public Detail[] Details {get;set;}
}
public class Detail
{
public string Sub1 {get;set;}
public string Sub2 {get;set;}
}
Create instance from Person class and initialize to instance after than
JavaScriptSerializer serializer =new JavaScriptSerializer();
var result=serializer.Serialize(instanceOfPerson);
"result" is json data
Assuming that you mean you want to create JSON string, you need to create those classes and use something like Newtonsoft JSON.net:
public class Item
{
public string Sub_Property1 { get; set; }
public string Sub_Property2 { get; set; }
}
public class Bars
{
public List<Item> items { get; set; }
}
public class Person
{
public List<string> Aliases { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public Bars Bars { get; set; }
}
Please read the documentation here: http://www.newtonsoft.com/json/help/html/Introduction.htm

How to get an item value of json using C#?

How to get an item value of json using C#?
json:
[{
ID: '6512',
fd: [{
titie: 'Graph-01',
type: 'graph',
views: {
graph: {
show: true,
state: {
group: 'DivisionName',
series: ['FieldWeight', 'FactoryWeight', 'Variance'],
graphType: 'lines-and-points'
}
}
}
}, {
titie: 'Graph-02',
type: 'Graph',
views: {
graph: {
show: true,
state: {
group: 'DivisionName',
series: ['FieldWeight', 'FactoryWeight', 'Variance'],
graphType: 'lines-and-points'
}
}
}
}]
}, {
ID: '6506',
fd: [{
titie: 'Map-01',
type: 'map',
views: {
map: {
show: true,
state: {
kpiField: 'P_BudgetAmount',
kpiSlabs: [{
id: 'P_BudgetAmount',
hues: ['#0fff03', '#eb0707'],
scales: '10'
}]
}
}
}
}]
}]
Above mentioned one is json, Here titie value will be get in a list
please help me...
My code is:
string dashletsConfigPath = Url.Content("~/Content/Dashlets/Dashlets.json");
string jArray = System.IO.File.ReadAllText(Server.MapPath(dashletsConfigPath));
List<string> lists = new List<string>();
JArray list = JArray.Parse(jArray);
var ll = list.Select(j => j["fd"]).ToList();
Here json will be converted in to JArray then
li got fd details then we got tite details on a list
If you just want a List<string> of the "titie" (sic) property values, this should work, using SelectMany:
List<string> result = list.SelectMany(
obj => obj["fd"]
.Select(inner => inner["titie"].Value<string>()))
.ToList()
This assumes that the JSON you posted is made valid by quoting property names.
I would recommend creating a class for your objects and use a DataContractSerializer to deserialize the JSON string.
[DataContract]
public class Container
{
[DataMember(Name="ID")]
public string ID { get; set; }
[DataMember(Name="fd")]
public Graph[] fd { get; set; }
}
[DataContract]
public class Graph
{
[DataMember(Name="title")]
public string Title { get; set; }
[DataMember(Name="type")]
public string Type { get; set; }
}
etc.
This will give you strongly typed classes around your JSON.
I'm not sure how you intend to use the data but you can collect all the titie values from your objects like this:
var arr = JArray.Parse(json);
var query =
from JObject obj in arr
from JObject fd in obj["fd"]
select new
{
Id = (string)obj["ID"],
Titie = (string)fd["titie"],
};
You can use json.net to deserialize json string like this:
public class Item
{
public string ID { get; set; }
public List<FD> fd { get; set; }
}
public class FD
{
public string titie { get; set; }
public string type { get; set; }
public Views views { get; set; }
}
public class Views
{
public Graph graph { get; set; }
}
public class Graph
{
public bool show { get; set; }
public State state { get; set; }
}
public class State
{
public string group { get; set; }
public string[] series { get; set; }
public string graphType { get; set; }
}
class Program
{
static void Main(string[] args)
{
string json = #"..."; //your json string
var Items = JsonConvert.DeserializeObject<List<Item>>(json);
List<string> tities = new List<string>();
foreach (var Item in Items)
{
foreach (var fd in Item.fd)
{
tities.Add(fd.titie);
}
}
}
}
First thing is your json format invalid. get the valid json below.
[{
"ID": "6512",
"fd": [{
"titie": "Graph-01",
"type": "graph",
"views": {
"graph": {
"show": true,
"state": {
"group": "DivisionName",
"series": ["FieldWeight", "FactoryWeight", "Variance"],
"graphType": "lines-and-points"
}
}
}
}, {
"titie": "Graph-02",
"type": "Graph",
"views": {
"graph": {
"show": true,
"state": {
"group": "DivisionName",
"series": ["FieldWeight", "FactoryWeight", "Variance"],
"graphType": "lines-and-points"
}
}
}
}]
}, {
"ID": "6506",
"fd": [{
"titie": "Map-01",
"type": "map",
"views": {
"map": {
"show": true,
"state": {
"kpiField": "P_BudgetAmount",
"kpiSlabs": [{
"id": "P_BudgetAmount",
"hues": ["#0fff03", "#eb0707"],
"scales": "10"
}]
}
}
}
}]
}]
And if you want to read items as separate strings use following code.
JArray jObject = JArray.Parse(json);
var ll = jObject.ToList();
You can use Newtonsoft Json Library.
Deserialize your json string with the model objects below
public class JsonWrapper
{
public string ID { get; set; }
public List<Fd> fd { get; set; }
}
public class Fd
{
public string titie { get; set; }
public string type { get; set; }
public Views views { get; set; }
}
public class Views
{
public Graph graph { get; set; }
}
public class Graph
{
public bool show { get; set; }
public State state { get; set; }
}
public class State
{
public string group { get; set; }
public List<string> series { get; set; }
public string graphType { get; set; }
}
Declare on object of JsonWrapper class and deserialize the json string to it.
JsonWrapper jsonWrapper = new JsonWrapper();
jsonWrapper = (JsonWrapper)JsonConvert.DeserializeObject(jsonString, jsonWrapper.getType());
Then you can access all the lists and properties from the jsonWrapper object.

Categories

Resources