Deserialize Newtonsoft Json data with Dynamic property name - C# - c#

I have referred to this question, which is similar to my issue but unable to fix the issue completely since the data structure is different and I am not able to figure-out how to apply this solution to my example data given below:
{
"result": {
"RITM2572913": {
"number": "RITM2572913",
"state": "1",
"stage": "fulfillment",
"Sys_ID": "220e89681b31b384e3a0a79b2d4bcbf3",
"requested_for": "1d1673c4dbda5b0072a85099dc9619b0",
"Contoso_requested_for": "requested_for:1d1673c4dbda5b0072a85099dc9619b0,var_name_arr:",
"Contoso_sc_Purposeofthef5request": "Add",
"Contoso_Sc_Contactinfo": "Contact ",
"Contoso_sc_Appname": "Application ",
"Contoso_sc_Description": "Description",
"Contoso_special_instructions": "special_instructions:",
"business_justification": "Justification ",
"Contoso_business_justification": "busess_justification:Justification",
"Contoso_catalog_item_footer": "owner_info:"
}
}
}
I have the response data like this and need to de-serialize it to fit in the object model given below:
public class RITMGETRequestResponse
{
public RITMDetails result { get; set; }
public class RITMDetails
{
public string business_justification { get; set; }
public string number { get; set; }
public string requested_for { get; set; }
public string stage { get; set; }
public string state { get; set; }
public string Sys_ID { get; set; }
public string var_name_arr { get; set; }
public string Contoso_business_justification { get; set; }
public string Contoso_catalog_item_footer { get; set; }
public string Contoso_requested_for { get; set; }
public string Contoso_sc_Appname { get; set; }
public string Contoso_Sc_Contactinfo { get; set; }
public string Contoso_sc_Description { get; set; }
public string Contoso_sc_Purposeofthef5request { get; set; }
public string Contoso_special_instructions { get; set; }
}
}
In this case RITM number is dynamic. I need to get the Sys_ID and other properties of this JSON. How do I de-serialize this JSON response to get these values?

straightforward example:
used a JSONProperty attribute to map result values of a dynamic property name
class Program
{
static void Main(string[] args)
{
var deserialise = JsonConvert.DeserializeObject<RITMRequestResponse>("{\"result\": {\"123\" : { \"number\" : \"123\" }}}");
Console.WriteLine(deserialise);
Console.ReadLine();
}
}
public class RITMRequestResponse
{
[JsonProperty(PropertyName = "result")]
public Dictionary<string, RITMDetails> RITMDetails { get; set; }
}
public class RITMDetails
{
public string Number { get; set; }
}

Related

Deserialize nested JSON, C# [duplicate]

This question already has an answer here:
Deserialize Nested JSON
(1 answer)
Closed 1 year ago.
I need to deserialize some JSON with this format:
{
"message": {
"header": {
"status_code": 200,
"execute_time": 0.29062294960022,
"available": 10000
},
"body": {
"track_list": [
{
"track": {
"track_id": 45085706,
"track_name": "Love Overdose (Deboa & Hannah Holland Remix)",
"primary_genres": {
"music_genre_list": [
{
"music_genre": {
"music_genre_name": "Dance"
}
}
]
}
}
}
]
}
}
}
I have these classes which I got from online generator, so I assume they are ok.
public class Header
{
public int status_code { get; set; }
public double execute_time { get; set; }
public int available { get; set; }
}
public class MusicGenre
{
public int music_genre_id { get; set; }
public int music_genre_parent_id { get; set; }
public string music_genre_name { get; set; }
public string music_genre_name_extended { get; set; }
public string music_genre_vanity { get; set; }
}
public class MusicGenreList
{
public MusicGenre music_genre { get; set; }
}
public class PrimaryGenres
{
public List<MusicGenreList> music_genre_list { get; set; }
}
public class Track
{
public int track_id { get; set; }
public string track_name { get; set; }
public List<object> track_name_translation_list { get; set; }
public int track_rating { get; set; }
public int commontrack_id { get; set; }
public int instrumental { get; set; }
public int #explicit { get; set; }
public int has_lyrics { get; set; }
public int has_subtitles { get; set; }
public int has_richsync { get; set; }
public int num_favourite { get; set; }
public int album_id { get; set; }
public string album_name { get; set; }
public int artist_id { get; set; }
public string artist_name { get; set; }
public string track_share_url { get; set; }
public string track_edit_url { get; set; }
public int restricted { get; set; }
public DateTime updated_time { get; set; }
public PrimaryGenres primary_genres { get; set; }
}
public class TrackList
{
public Track track { get; set; }
}
public class Body
{
public List<TrackList> TrackList { get; set; }
}
public class Message
{
public Header header { get; set; }
public Body body { get; set; }
}
public class Root
{
public Message message { get; set; }
}
I tried to deserialize the JSON with this code:
using (StreamReader r = new StreamReader(#"c:\users\xxxx\desktop\1.json"))
{
string json = r.ReadToEnd();
var tracks = JsonConvert.DeserializeObject<Track>(json);
}
but I got nothing. I'm new to this; made it with simpler JSON, but I can't figure out how to do it with this code. I want to print a list with just the song names.
If anyone can help me I would appreciate it!
There are a couple of problems here:
In your Body class, the TrackList property does not match the JSON. The corresponding property in the JSON is called track_list. The class properties must either exactly match the JSON (ignoring case) or else you need to use a [JsonProperty] attribute on the property to indicate what the JSON name will be. For example:
public class Body
{
[JsonProperty("track_list")]
public List<TrackList> TrackList { get; set; }
}
You are attempting to deserialize into the Track class, but you should be deserializing to Root since that represents the root of the JSON.
var root = JsonConvert.DeserializeObject<Root>(json);
Once you have deserialized to Root you can "drill down" to print out the tracks.
foreach (var item in root.message.body.TrackList)
{
Console.WriteLine(item.track.track_name);
}
Fiddle: https://dotnetfiddle.net/JnljGU

Serializing to model - serialize node to choice of two objects

I have a JSON file of following structure.
{
title: {
title: "",
episode_title: ""
},
series: {
season: "",
episode: ""
}
content_description: {
???
}
}
, where content_description may have one of following formats:
content_description: {
language: "",
short_synapsis: "",
medium_synopsis: "",
long_synopsis: "",
oneliner: ""
}
OR
content_description: {
text: "",
category: "",
level: "",
source: ""
}
I want to serialize it to C# model using Newtonsoft Json.NET JsonConvert.DeserializeObject(string value) method. So far, I've created a following content_description model:
public class ContentDescriptions
{
public string language { get; set; }
public string short_synopsis { get; set; }
public string medium_synopsis { get; set; }
public string long_synopsis { get; set; }
public string short_season_synopsis { get; set; }
public string medium_season_synopsis { get; set; }
public string long_season_synopsis { get; set; }
public string short_episode_synopsis { get; set; }
public string medium_episode_synopsis { get; set; }
public string long_episode_synopsis { get; set; }
public string oneliner { get; set; }
public string text { get; set; }
public string category { get; set; }
public string level { get; set; }
public string source { get; set; }
}
This works, but is there a way to serialize element with one name to one of two models depending if its structure? For example, having two content_description model fields in my root model and filling one of them while leaving the other one null?
Would a container class work?
class MyAmazingClass {
ContentDescriptionsA A {get; set;}
ContentDescriptionsB B {get; set;}
}
and then you could (de)serialise object of this class.
If I understand correctly from your limited amount of information you expect to get a json string that can be either A or B. You are nog interested in B as it can be instantiated with null values or empty.
In that case you can deserialize with object A (ContentDescriptionsA) everytime. The properties of the class will be filled whena JsonString with contents of A come through and the properties will be null if an object of B comes through.
Here's a simple Console application that you can rebuild to play around with the concept. (Sidenote: you could also create a class that holds ALL the properties of both JsonStrings, but then the properties of B will also be filled)
using System.Text.Json;
namespace TestJson
{
class Program
{
static void Main(string[] args)
{
var a = new ContentDescriptionsA() { language = "NederlandsA"};
var b = new ContentDescriptionsB() { text = "TextB" };
var jsonstringA = JsonSerializer.Serialize(a);
var jsonstringB = JsonSerializer.Serialize(b);
var deserializeA = JsonSerializer.Deserialize<ContentDescriptionsA>(jsonstringA); // properties of a FILLED, props of b NULL
var deserializeB = JsonSerializer.Deserialize<ContentDescriptionsA>(jsonstringB); // all properties NULL
}
}
public class ContentDescriptionsA
{
public string language { get; set; }
public string short_synopsis { get; set; }
public string medium_synopsis { get; set; }
public string long_synopsis { get; set; }
public string short_season_synopsis { get; set; }
public string medium_season_synopsis { get; set; }
public string long_season_synopsis { get; set; }
public string short_episode_synopsis { get; set; }
public string medium_episode_synopsis { get; set; }
public string long_episode_synopsis { get; set; }
public string oneliner { get; set; }
}
public class ContentDescriptionsB
{
public string text { get; set; }
public string category { get; set; }
public string level { get; set; }
public string source { get; set; }
}
}

Creating a C# class from convoluted JSON object where dynamic variable would be class name [duplicate]

This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Closed 2 years ago.
I'm trying to query the most important information from wikipedia articles using the wikimedia API. Within my code I have the following line:
WikiArticleModel article = await response.Content.ReadAsAsync<WikiArticleModel>().ConfigureAwait(false);
This is a example of the way my JSON object looks like when testing on the article from the planet Jupiter:
{
"batchcomplete": "",
"query": {
"normalized": [
{
"from": "jupiter",
"to": "Jupiter"
}
],
"pages": {
"38930": {
"pageid": 38930,
"ns": 0,
"title": "Jupiter",
"extract": ">>> Her comes the first section of the article, which I deleted to make
this shorter <<<",
"description": "Fifth planet from the Sun and largest planet in the Solar System",
"descriptionsource": "local",
"original": {
"source": "https://upload.wikimedia.org/wikipedia/commons/2/2b/Jupiter_and_its_shrunken_Great_Red_Spot.jpg",
"width": 940,
"height": 940
}
}
}
}
}
The question is now, how should my WikiArticleModel class look like? Using the build-in VS Studio too "Paste JSON as class" I get the following result:
public class WikiArticleModel
{
public string batchcomplete { get; set; }
public Query query { get; set; }
}
public class Query
{
public Normalized[] normalized { get; set; }
public Pages pages { get; set; }
}
public class Pages
{
public _38930 _38930 { get; set; }
}
public class _38930
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
public string description { get; set; }
public string descriptionsource { get; set; }
public Original original { get; set; }
}
public class Original
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Normalized
{
public string from { get; set; }
public string to { get; set; }
}
Which is OK and what I would expect, except for the class _38930, which is just the pageid and would change with every query.
What is the correct way to deserialize this object? Or is it a better approach to just get a object as response and fill the model class manually in this case?
Additionally, I actually only need certain parameters from the JSON object (e.g. title, extract, description,..) - is there a way to get these directly into a model class containing only the properties I need?
This is the way to do it natively, Pages is actually a Dictionary<int, Page>.
public class WikiArticleModel
{
public string batchcomplete { get; set; }
public Query query { get; set; }
}
public class Query
{
public List<Normalized> normalized { get; set; }
public Pages pages { get; set; }
}
[JsonDictionary]
public class Pages : Dictionary<int, Page> { }
public class Page
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
public string description { get; set; }
public string descriptionsource { get; set; }
public Original original { get; set; }
}
public class Original
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Normalized
{
public string from { get; set; }
public string to { get; set; }
}
I would recommend using JObject.Parse from Newtonsoft.Json.Linq and parsing it based on the name of the keys that page has. Something like this,
public class Page
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
public string description { get; set; }
public string descriptionsource { get; set; }
public Original original { get; set; }
}
public class Original
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Normalized
{
public string from { get; set; }
public string to { get; set; }
}
// you can deserialize like this,
var jobj = JObject.Parse(json);
var props = ((JObject)jobj["query"]["pages"]).Properties();
Page page = JsonConvert.DeserializeObject<Page>(jobj["query"]["pages"][props.First().Name].ToString());
You can use a foreach loop on each of the properties of pages and iterate through those as well (instead of using props.First().

Deserialize json (javascript object) to c# object

i have following javascript object it looks like json but when i parse it as json i am getting errors:
{
"1": {
"name": "Manheim Simulcast ",
"items": {
"2": {
"pos": "52",
"name": "NY - Manheim Albany",
"address": "",
"zip": "12201",
"coords": ""
}
}
}
}
and following classes:
public class auction_js_min
{
public auction_id auction_id { set; get; }
}
public class auction_id
{
public string name { set; get; }
public Items items { set; get; }
}
public class Items
{
public Sub_auction_id sub_auction_id { set; get; }
}
public class Sub_auction_id
{
public string pos { get; set; }
public string name { get; set; }
public string address { get; set; }
public string zip { get; set; }
public string coords { get; set; }
}
when i deserialize it to C# object im getting empty object:
auction_js_min obj = JsonConvert.DeserializeObject<auction_js_min>(auction_js);
is any idea how to fix it? javascript object is too big 87000 symbol and i want iterate over objects and check values.
I think what you're running into here is that your objects are numbered and you can't name a class with just number. In this case your model doesn't match your JSON so all you're going to get is null. You need to modify your model to match the JSON you have and then you can map that DTO model to something nicer to use in C#.
Here's an example model that deserializes your JSON:
public class auction_id
{
public string name { set; get; }
public IDictionary<int, Sub_auction_id> items { set; get; }
}
public class Sub_auction_id
{
public string pos { get; set; }
public string name { get; set; }
public string address { get; set; }
public string zip { get; set; }
public string coords { get; set; }
}
And then deserialize like so:
public void Deserialize()
{
var auction = JsonConvert.DeserializeObject<IDictionary<int, auction_id>>(json);
}
I think you can make use of JsonProperty here.
Usually these names are invalid but they could be parsed like this.
public class auction_js_min
{
[JsonProperty("1")]
public auction_id auction_id { set; get; }
}
public class auction_id
{
public string name { set; get; }
public Items items { set; get; }
}
public class Items
{
[JsonProperty("2")]
public Sub_auction_id sub_auction_id { set; get; }
}
public class Sub_auction_id
{
public string pos { get; set; }
public string name { get; set; }
public string address { get; set; }
public string zip { get; set; }
public string coords { get; set; }
}
Thats because of single quotes. Both of the following will work:
If you know your object is correct, skip the string quotation and directly eval it:
eval({'1': {'name': 'Manheim Simulcast','items':{'2':{'pos': '52','name': 'NY - Manheim Albany','address': '','zip': '12201','coords': ''}}}})
Or use double quotes inside JSON and single quotes to make it a string likr this:
JSON.parse('{"1": {"name": "Manheim Simulcast","items":{"2":{"pos": "52","name": "NY - Manheim Albany","address": "","zip": "12201","coords": ""}}}}')
As far as parsing them to a C# object. It can be multiple things, need more details.

How to deserialize JSON to .NET object using JSON.NET?

I have a JSON object like the following
{
"data": [
{
"id": "18128270850211_49239570772655",
"from": {
"name": "Someone Unimportant",
"id": "57583427"
}
/* more stuff */
}
]
}
I want to parse it using JSON.NET,
FacebookResponse<FacebookPost> response = JsonConvert.DeserializeObject<FacebookResponse<FacebookPost>>(json);
internal class FacebookResponse<T> where T : class
{
public IList<T> Data { get; set; }
public FacebookResponsePaging Paging { get; set; }
}
public class FacebookPost
{
public string Id { get; set; }
[JsonProperty("to.data.id")]
public string FeedId { get; set; }
[JsonProperty("from.id")]
public string UserId { get; set; }
[JsonProperty("created_time")]
public DateTime CreatedTime { get; set; }
[JsonProperty("updated_time")]
public DateTime UpdatedTime { get; set; }
public string Type { get; set; } // TODO: Type enum??
public string Message { get; set; }
public string Link { get; set; }
public string Name { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
}
Everything comes through except for the FeedId and the UserId properties. How should I be mapping these?
public class From
{
public string name { get; set; }
public string id { get; set; }
}
public class Datum
{
public string id { get; set; }
public From from { get; set; }
}
public class FacebookPost
{
public List<Datum> data { get; set; }
}
internal class FacebookResponse<T> where T : class
{
public IList<T> Data { get; set; }
public FacebookResponsePaging Paging { get; set; }
}
FacebookResponse<FacebookPost> response = JsonConvert.DeserializeObject<FacebookResponse<FacebookPost>>(json);
Try below code :)
Use this site to get the object for .net
Then you can use JSON.Net to deserialize: ex.JsonConvert.DeserializeObject(input) iirc

Categories

Resources