Deserializing list of items - c#

I have following sample Json string:
{"Items":[{"Id":"20","CaptureCategoryTypeId":5021,"Name":"24270","Description":"FSH CARRIBEAN CAPTAIN","IsEnabled":true}],"TotalResults":0}
I need to deserialize the same but I don't want to keep my class name as following:
public class Item
{
public string Id { get; set; }
public int CaptureCategoryTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsEnabled { get; set; }
}
public class RootObject
{
public List<Item> Items { get; set; }
public int TotalResults { get; set; }
}
I want to keep custom class name such DataDetails. How that can be achieved in c#?

I don't quite understand what your question is but you can just change the class names to whatever you want. Below is a working example.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string JSONInput = #"{""Items"":[{""Id"":""20"",""CaptureCategoryTypeId"":5021,""Name"":""24270"",""Description"":""FSH CARRIBEAN CAPTAIN"",""IsEnabled"":true}],""TotalResults"":0}";
BlahObject deserializedProduct = JsonConvert.DeserializeObject<BlahObject>(JSONInput);
Console.ReadKey();
}
}
public class DataDetails
{
public string Id { get; set; }
public int CaptureCategoryTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsEnabled { get; set; }
}
public class BlahObject
{
public List<DataDetails> Items { get; set; }
public int TotalResults { get; set; }
}
}

Related

How do I deserialize JSON correctly in C#

I am trying to deserialize the Supreme New York JSON but I am getting an error.
I used json2csharp.com to convert the Json into classes.
Then I summarised them all into one called items
namespace SUPBOTTESTING
{
public class items
{
public string name { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public string image_url_hi { get; set; }
public int price { get; set; }
public int sale_price { get; set; }
public bool new_item { get; set; }
public int position { get; set; }
public string category_name { get; set; }
public int price_euro { get; set; }
public int sale_price_euro { get; set; }
}
}
using System;
using System.Net;
using System.Web.Script.Serialization;
namespace SUPBOTTESTING
{
class Program
{
public static void Main()
{
{
string shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
JavaScriptSerializer shop_object = new JavaScriptSerializer();
items[] shirt_stock = shop_object.Deserialize<items[]>(shop_json);
Console.WriteLine(shirt_stock[1]);
}
}
}
}
I am getting the error:
Default constructor not found for type SUPBOTTESTING.items[]
Ok here is the solution. You have the correct idea but you need to understand the structure of your Json data.
You are deserializing it into an array of Object whereas your Json data returned itself is not an Array or a List. It contains child nodes that are an array so you need to structure your Object accordingly to get a successful breakdown of data.
Here I have used Newtonsoft to deserialise the Json data into an Object.
I have tested the code and it returns a list of Shirts
static void Main(string[] args)
{
var shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
var shirt_stock = JsonConvert.DeserializeObject<StockObject>(shop_json);
// Picking shirts to demonstrate how to display values for all shirts
var shirts = shirt_stock.products_and_categories.Shirts;
foreach (var shirt in shirts)
{
var shirtBuilder = new StringBuilder();
shirtBuilder.AppendLine($"Name: {shirt.name}");
shirtBuilder.AppendLine($"ID: {shirt.id.ToString()}");
shirtBuilder.AppendLine($"New Item: {shirt.new_item.ToString()}");
shirtBuilder.AppendLine($"Category Name: {shirt.category_name}");
Console.WriteLine(shirtBuilder);
}
}
public class StockObject
{
public ProductsCats Products_and_categories { get; set; }
}
public class ProductsCats
{
public Details[] Shirts { get; set; }
public Details[] Bags { get; set; }
public Details[] Accessories { get; set; }
public Details[] Pants { get; set; }
public Details[] Jackets { get; set; }
public Details[] Skates { get; set; }
public Details[] Hats { get; set;}
public Details[] Sweatshirts { get; set;}
[JsonProperty("Tops/Sweaters")]
public Details[] TopsSweaters { get;set;}
public Details[] New { get; set; }
}
public class Details
{
public string name { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public string image_url_hi { get; set; }
public int price { get; set; }
public int sale_price { get; set; }
public bool new_item { get; set; }
public int position { get; set; }
public string category_name { get; set; }
public int price_euro { get; set; }
public int sale_price_euro { get; set; }
}
You see what I have done here?
So your Json data contains a parent node products_and_categories and its child node contains an array of Shirts which is what you are after?
StockObject class contains the Parent property called Products_and_categories of type object ProductsCats.
ProductsCats Object contains the property Shirts of type Details which is an array and will be used during the deserialising process.
Hope this helps?
Well you do not need to specify a default constructor. What is wrong is, i think you didn't check the json data properly. Because your items class is not in the first level of json. You need to create a couple of classes to be more accurate on deserializing.
First of all you need to know that this json file has a lot of bad-smells and bad-practices on it.
Note that you need to install Newtonsoft.Json before going further. It is much more convenient way to deserialize a json into C# classes.
Yet, i wrote a proper way of deserializing it:
public class BaseItem
{
public string Name { get; set; }
public int Id { get; set; }
public string Image_url { get; set; }
public string Image_url_hi { get; set; }
public int Price { get; set; }
public int Sale_price { get; set; }
public bool New_item { get; set; }
public int Position { get; set; }
public string Category_name { get; set; }
public int Price_euro { get; set; }
public int Sale_price_euro { get; set; }
}
public class Shirt : BaseItem { }
public class Bag : BaseItem { }
public class Accessory : BaseItem { }
public class Pant : BaseItem { }
public class Jacket : BaseItem { }
public class Skate : BaseItem { }
public class Hat : BaseItem { }
public class Sweatshirt : BaseItem { }
public class TopsSweater : BaseItem { }
public class New : BaseItem { }
public class RootObject
{
public List<object> Unique_image_url_prefixes { get; set; }
public ProductsAndCategories Products_and_categories { get; set; }
public string Release_date { get; set; }
public string Release_week { get; set; }
}
public class ProductsAndCategories
{
public List<Shirt> Shirts { get; set; }
public List<Bag> Bags { get; set; }
public List<Accessory> Accessories { get; set; }
public List<Pant> Pants { get; set; }
public List<Jacket> Jackets { get; set; }
public List<Skate> Skate { get; set; }
public List<Hat> Hats { get; set; }
public List<Sweatshirt> Sweatshirts { get; set; }
[JsonProperty("Tops/Sweaters")]
public List<TopsSweater> TopsSweaters { get; set; }
public List<New> New { get; set; }
}
First of all, all of your items are have the same properties on them, yet, they all marked as different properties. So that, i created a BaseItem class and other empty classes which are inherited from that.
Also you need other 2 classes -which are RootObject and ProductsAndCategories- to provide data on them. Note that there is a JsonProperty("blabla") on the TopsSweaters property. Because, in json file it is Tops/Sweaters, and you can not use that name on a C# property. That is the attribute for using that kind of different property names.
Then you can populate your object like this:
static void Main(string[] args)
{
var jsonData = "https://www.supremenewyork.com/mobile_stock.json";
string shopJson = new WebClient().DownloadString(jsonData);
RootObject shirtStock = JsonConvert.DeserializeObject<RootObject>(shopJson); //All json data is in this variable
Console.WriteLine(shirtStock.Products_and_categories.Shirts[1]);
}
Your problem is that youre using a class to load the JSON data in, where you should use a struct, alternatively you can also create a constructor that takes no arguments and sets all variables to default values, which is a lot of work so just replace class with struct:
public struct Items
{
public string Name { get; set; }
public int Id { get; set; }
public string Image_Url { get; set; }
public string Image_Url_Hi { get; set; }
public int Price { get; set; }
public int Sale_Price { get; set; }
public bool New_item { get; set; }
public int Position { get; set; }
public string Category_Name { get; set; }
public int Price_Euro { get; set; }
public int Sale_Price_Euro { get; set; }
}
Also please stick to C# naming conventions, you should be able to do this since most JSON parsers are case insensitive by default.
Some more info: A class doesnt really has a proper default constructor if you dont define one, where as a struct always has a default constructor, so when the JSON parser wants to init your class it cant because a default constructor isnt definded.
static void Main(string[] args)
{
string shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
JavaScriptSerializer shop_object = new JavaScriptSerializer();
var shirt_stock = shop_object.Deserialize<NewYarkItems>(shop_json);
var v = shirt_stock;
}
public class NewYarkItems
{
public dynamic unique_image_url_prefixes { get; set; }
public products_and_categories products_And_Categories { get; set; }
public string release_date { get; set; }
public string release_week { get; set; }
}
public class products_and_categories
{
public List<items> Jackets { get; set; }
}
public class items
{
public string name { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public string image_url_hi { get; set; }
public int price { get; set; }
public int sale_price { get; set; }
public bool new_item { get; set; }
public int position { get; set; }
public string category_name { get; set; }
public int price_euro { get; set; }
public int sale_price_euro { get; set; }
}

How to parse specific data from JSON response [duplicate]

This question already has answers here:
How can I deserialize JSON with C#?
(19 answers)
Closed 5 years ago.
I am trying to parse JSON response using newtownsoft.json trying to parse the followers count and writeline.
This is the code:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
namespace J2C
{
class Checker
{
static void Main(string[] args)
{
var client = new WebClient();
var text = client.DownloadString("https://www.instagram.com/2saleapp/?__a=1");
User userObject = JsonConvert.DeserializeObject<User>(text);
Console.WriteLine("Followers count =" + userObject.followed_by);
Console.ReadKey();
}
}
}
and this is the API response:
{
"user": {
"biography": "Install 2Sale app to post your AD instantly!\nSnap, post, and sell. Its time to sale.",
"blocked_by_viewer": false,
"country_block": false,
"external_url": "http://autoigs.com/2sale_install",
"external_url_linkshimmed": "http://l.instagram.com/?u=http%3A%2F%2Fautoigs.com%2F2sale_install&e=ATMoKdz87_iz044M0ebrfU95WQT7JqBpnlGiGH9UDOsn7dRax7G6ZMxjh7wMuHY",
"followed_by": {
"count": 6511
},
"followed_by_viewer": false,
"follows": {
"count": 19
},
I just want to WriteLine Followed_by count numbers.
Any one can help me?
thank you
Copy the raw json to the clipboard. In Visual Studio menu select Edit > Paste Special > Paste JSON As Classes (this item is present at least since version VS2015. For earlier versions see). This will generate a set of classes.
public class Rootobject
{
public User user { get; set; }
public string logging_page_id { get; set; }
}
public class User
{
public string biography { get; set; }
public bool blocked_by_viewer { get; set; }
public bool country_block { get; set; }
public string external_url { get; set; }
public string external_url_linkshimmed { get; set; }
public Followed_By followed_by { get; set; }
public bool followed_by_viewer { get; set; }
public Follows follows { get; set; }
public bool follows_viewer { get; set; }
public string full_name { get; set; }
public bool has_blocked_viewer { get; set; }
public bool has_requested_viewer { get; set; }
public string id { get; set; }
public bool is_private { get; set; }
public bool is_verified { get; set; }
public string profile_pic_url { get; set; }
public string profile_pic_url_hd { get; set; }
public bool requested_by_viewer { get; set; }
public string username { get; set; }
public object connected_fb_page { get; set; }
public Media media { get; set; }
}
public class Followed_By
{
public int count { get; set; }
}
public class Follows
{
public int count { get; set; }
}
public class Media
{
public Node[] nodes { get; set; }
public int count { get; set; }
public Page_Info page_info { get; set; }
}
public class Page_Info
{
public bool has_next_page { get; set; }
public string end_cursor { get; set; }
}
public class Node
{
public string __typename { get; set; }
public string id { get; set; }
public bool comments_disabled { get; set; }
public Dimensions dimensions { get; set; }
public object gating_info { get; set; }
public string media_preview { get; set; }
public Owner owner { get; set; }
public string thumbnail_src { get; set; }
public object[] thumbnail_resources { get; set; }
public bool is_video { get; set; }
public string code { get; set; }
public int date { get; set; }
public string display_src { get; set; }
public string caption { get; set; }
public Comments comments { get; set; }
public Likes likes { get; set; }
public int video_views { get; set; }
}
public class Dimensions
{
public int height { get; set; }
public int width { get; set; }
}
public class Owner
{
public string id { get; set; }
}
public class Comments
{
public int count { get; set; }
}
public class Likes
{
public int count { get; set; }
}
Next, use the Rootobject. It's supposed to work.
var client = new WebClient();
var text = client.DownloadString("https://www.instagram.com/2saleapp/?__a=1");
Rootobject rootObject = JsonConvert.DeserializeObject<Rootobject>(text);
Console.WriteLine("Followers count =" + rootObject.user.followed_by.count);
In general, you should change the naming to conform to the generally accepted naming rules. You should use the JsonProperty attribute.
public class Rootobject
{
[JsonProperty("user")]
public User User { get; set; }
[JsonProperty("logging_page_id")]
public string LoggingPageId { get; set; }
}
And so on.
Create a class with name User in order to deserialize json string to User.
public class User
{
public string biography { get; set; }
public bool blocked_by_viewer { get; set; }
public bool country_block { get; set; }
public string external_url { get; set; }
public string external_url_linkshimmed { get; set; }
public FollowedBy followed_by { get; set; }
public string followed_by_viewer { get; set; }
public Follow follows { get; set; }
}
public class FollowedBy
{
public int count { get; set; }
}
public class Follow
{
public int count { get; set; }
}
After getting json string result using the below line for DeserializeObject to User and then assign it to new User object , after that use userObject for showing result.
User userObject = JsonConvert.DeserializeObject<User>(jsonString);
Now you have a user object that fill property with the API response.

JsonConvert.DeserializeObject not working sometimes

I'm trying to Deserialize some json using JsonConver.DeserializeObject. however it's not working on some json from the api I'm using. here is a link that does not work: https://api.pokemontcg.io/v1/cards?setCode=smp
and here is a link that does work. https://api.pokemontcg.io/v1/cards?setCode=sm2
I'm not sure why it sometimes works and sometimes not. The data that comes out of it is very similar to each other, just different cards.
Here is the code:
public static async Task<T> GetDataAsync<T>(this HttpClient client, string address, string querystring)
where T : class
{
var uri = address;
if (!string.IsNullOrEmpty(querystring))
{
uri += querystring;
}
var httpMessage = await client.GetStringAsync(uri);
var jsonObject = JsonConvert.DeserializeObject<T>(httpMessage);
return jsonObject;
}
Now my card class
namespace CardAppReal.Lib.Models
{
public class Card
{
public string id { get; set; }
public string name { get; set; }
public string imageUrl { get; set; }
public string imageUrlHiRes { get; set; }
public string supertype { get; set; } // if pokemon, trainer or energy
public string setcode { get; set; }
public int number { get; set; }
public string set { get; set; }
}
}
With a root
using System.Collections.Generic;
using CardAppReal.Lib.Models;
namespace CardAppReal.Lib.Entities
{
public class RootCard
{
public List<Card> cards { get; set; }
}
}
If u could help me out I would find it amazing.
I have tested your json.
this is the Model
namespace Test
{
public class Attack
{
public List<string> cost { get; set; }
public string name { get; set; }
public string text { get; set; }
public string damage { get; set; }
public int convertedEnergyCost { get; set; }
}
public class Weakness
{
public string type { get; set; }
public string value { get; set; }
}
public class Resistance
{
public string type { get; set; }
public string value { get; set; }
}
public class Ability
{
public string name { get; set; }
public string text { get; set; }
public string type { get; set; }
}
public class Card
{
public string id { get; set; }
public string name { get; set; }
public int nationalPokedexNumber { get; set; }
public string imageUrl { get; set; }
public string imageUrlHiRes { get; set; }
public string subtype { get; set; }
public string supertype { get; set; }
public string hp { get; set; }
public List<string> retreatCost { get; set; }
public string number { get; set; }
public string artist { get; set; }
public string rarity { get; set; }
public string series { get; set; }
public string set { get; set; }
public string setCode { get; set; }
public List<string> types { get; set; }
public List<Attack> attacks { get; set; }
public List<Weakness> weaknesses { get; set; }
public List<Resistance> resistances { get; set; }
public string evolvesFrom { get; set; }
public Ability ability { get; set; }
public List<string> text { get; set; }
}
public class RootObject
{
public List<Card> cards { get; set; }
}
}
And this is how I call the Deserialize
RootObject root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(RootObject.WRONG_JSON);
(NB WRONG_JSON is your json string...)

C# JSON.NET invalid type

I am curenntly making an thunder storm app for windows phone but i have a problem.
When i have converted the JSON string to C# classes i have seen that the class names just contain numbers.
How can i deserialize the JSON String?
public class 904
{
public string id { get; set; }
public string name { get; set; }
public string name_url { get; set; }
public string region_path { get; set; }
}
public class Result
{
public 904 904 { get; set; }
}
public class RootObject
{
public bool status { get; set; }
public Result result { get; set; }
public int time_valid_to { get; set; }
}
The JSON string
{"status":true,"result":{"904":{"id":"904","name":"Wien Alsergrund","name_url":"wien_alsergrund","region_path":"oesterreich\/wien\/wien_alsergrund"}},"time_valid_to":1424978715}
It looks like the result property is effectively a map of results - so you can represent that with a Dictionary<,>. This works:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
public class ResultEntry
{
public string id { get; set; }
public string name { get; set; }
public string name_url { get; set; }
public string region_path { get; set; }
}
public class RootObject
{
public bool status { get; set; }
public Dictionary<int, ResultEntry> result { get; set; }
public int time_valid_to { get; set; }
}
class Test
{
static void Main()
{
string json = File.ReadAllText("json.txt");
var root = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(root.result[904].name);
}
}
I'd strongly recommend using cleaner property names and specifying attributes to tell Json.NET how to map them to JSON though.

JSON Web Request string to parsed data with JSON.NET

I am using .net to call to a webservice then parse it to usable data.
Right now I am experimenting with this call: http://www.reddit.com/r/all.json
Which returns: http://pastebin.com/AbV4yVuC
This is put in to a string, which I called jsontxt.
I am using JSON.NET to parse the information but it doesn't seem to be working. I initially tried to deserialize it as an object and it didn't work as nothing is put in to the variable
Then I tried to deserialize it as a dataset and I'm having no luck again. My error was
An unhandled exception of type 'Newtonsoft.Json.JsonException' occurred in Newtonsoft.Json.dll
MY CODE:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace tutorialresult1
{
class Program
{
static void Main(string[] args)
{
using (var webClient = new System.Net.WebClient())
{
var jsontxt = webClient.DownloadString("http://www.reddit.com/r/all.json");
// Console.Write(json);
// -----Deserializing by Object--------------
//MediaEmbed account = JsonConvert.DeserializeObject<MediaEmbed>(jsontxt);
//Console.WriteLine(account.width); //COMES OUT TO NULL
// -----Deserializing by DataSet--------------
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(jsontxt);
DataTable dataTable = dataSet.Tables["Children"];
Console.WriteLine(dataTable.Rows.Count);
}
}
public class MediaEmbed
{
public string content { get; set; }
public int width { get; set; }
public bool scrolling { get; set; }
public int height { get; set; }
}
.... //rest of classes here for each json which were generated with http://json2csharp.com/
}
}
I'm just trying to make the JSON easily accessible by parsing it.
Using json2charp I generated the following set of classes. Using those you should be able to deserialize the JSON into RootObject using JSON.NET.
var account = JsonConvert.DeserializeObject<RootObject>(jsontxt);
.
public class MediaEmbed
{
public string content { get; set; }
public int? width { get; set; }
public bool? scrolling { get; set; }
public int? height { get; set; }
}
public class Oembed
{
public string provider_url { get; set; }
public string description { get; set; }
public string title { get; set; }
public string url { get; set; }
public string type { get; set; }
public string author_name { get; set; }
public int height { get; set; }
public int width { get; set; }
public string html { get; set; }
public int thumbnail_width { get; set; }
public string version { get; set; }
public string provider_name { get; set; }
public string thumbnail_url { get; set; }
public int thumbnail_height { get; set; }
public string author_url { get; set; }
}
public class SecureMedia
{
public Oembed oembed { get; set; }
public string type { get; set; }
}
public class SecureMediaEmbed
{
public string content { get; set; }
public int? width { get; set; }
public bool? scrolling { get; set; }
public int? height { get; set; }
}
public class Oembed2
{
public string provider_url { get; set; }
public string description { get; set; }
public string title { get; set; }
public int thumbnail_width { get; set; }
public int height { get; set; }
public int width { get; set; }
public string html { get; set; }
public string version { get; set; }
public string provider_name { get; set; }
public string thumbnail_url { get; set; }
public string type { get; set; }
public int thumbnail_height { get; set; }
public string url { get; set; }
public string author_name { get; set; }
public string author_url { get; set; }
}
public class Media
{
public string type { get; set; }
public Oembed2 oembed { get; set; }
}
public class Data2
{
public string domain { get; set; }
public object banned_by { get; set; }
public MediaEmbed media_embed { get; set; }
public string subreddit { get; set; }
public string selftext_html { get; set; }
public string selftext { get; set; }
public object likes { get; set; }
public SecureMedia secure_media { get; set; }
public string link_flair_text { get; set; }
public string id { get; set; }
public int gilded { get; set; }
public SecureMediaEmbed secure_media_embed { get; set; }
public bool clicked { get; set; }
public bool stickied { get; set; }
public string author { get; set; }
public Media media { get; set; }
public int score { get; set; }
public object approved_by { get; set; }
public bool over_18 { get; set; }
public bool hidden { get; set; }
public string thumbnail { get; set; }
public string subreddit_id { get; set; }
public object edited { get; set; }
public string link_flair_css_class { get; set; }
public object author_flair_css_class { get; set; }
public int downs { get; set; }
public bool saved { get; set; }
public bool is_self { get; set; }
public string permalink { get; set; }
public string name { get; set; }
public double created { get; set; }
public string url { get; set; }
public object author_flair_text { get; set; }
public string title { get; set; }
public double created_utc { get; set; }
public int ups { get; set; }
public int num_comments { get; set; }
public bool visited { get; set; }
public object num_reports { get; set; }
public object distinguished { get; set; }
}
public class Child
{
public string kind { get; set; }
public Data2 data { get; set; }
}
public class Data
{
public string modhash { get; set; }
public List<Child> children { get; set; }
public string after { get; set; }
public object before { get; set; }
}
public class RootObject
{
public string kind { get; set; }
public Data data { get; set; }
}
You are trying to deserialize a json-string into a dataset-object. But the json-string doesn't have the format of a dataset. So you need to create a class which matches the json or deserialize it into a dictionary or sth. like this.
Have you tried deserialize using the following? Seems to be more robust for me.
using System.Web.Script.Serialization;
...
var x = new JavaScriptSerializer().Deserialize<Obj_type>(jsonstring);
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer%28v=vs.110%29.aspx
as purplej0kr mentioned you will need to have a .Net model to use for Obj_type (and it will need to match the object you are parsing) or this will not work.
You will need the System.Web.Extensions.dll referenced in your project (right click add reference, dll is usually under 'Assemblies'). Otherwise:
Where can I find the assembly System.Web.Extensions dll?

Categories

Resources