C
C#3y ago
Owen

❔ JSON array to List KeyValuePair with Newtonsoft.JSON?

As the title reads, i'm attempting to load a config file (which successfully works) except I am struggling to figure out how I can take in my image assets as a KeyValuePair with the JSON name and value being the parameters. Here's my JSON code snippet:
{
"image_asset_urls": [

{
"bot_icon":"test.com/test.png"
}

]
}
{
"image_asset_urls": [

{
"bot_icon":"test.com/test.png"
}

]
}
Here's my C# translation using Newtonsoft.Json:
[JsonProperty("image_asset_urls")]
public List<KeyValuePair<string, string>>? Images { get; set; }
[JsonProperty("image_asset_urls")]
public List<KeyValuePair<string, string>>? Images { get; set; }
How would I correctly do this? Thanks.
44 Replies
TheRanger
TheRanger3y ago
you should let a site like https://json2csharp.com/ generate C# classes out of your json for you
Convert JSON to C# Classes Online - Json2CSharp Toolkit
Convert any JSON object to C# classes online. Json2CSharp is a free toolkit that will help you generate C# classes on the fly.
TheRanger
TheRanger3y ago
here's what it generated from ur current json code snippet
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class ImageAssetUrl
{
public string bot_icon { get; set; }
}

public class Root
{
public List<ImageAssetUrl> image_asset_urls { get; set; }
}
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class ImageAssetUrl
{
public string bot_icon { get; set; }
}

public class Root
{
public List<ImageAssetUrl> image_asset_urls { get; set; }
}
you can change the property name to Image and put the attribute [JsonProperty("image_asset_urls")] above the property
Hulkstance
Hulkstance3y ago
https://discord.com/channels/143867839282020352/1042207799440060497/1042211981320519751 mtreit just showed in a different post that there was a such feature in VS/Rider which automatically parses JSON to C# objects, so you don't have to use https://json2csharp.com/ 🙂
MODiX
MODiX3y ago
mtreit#6470
Quoted by
From mtreit#6470
React with ❌ to remove this embed.
Owen
OwenOP3y ago
Thanks for the response - i'm struggling to implement this. How would I go about doing this while also ensuring no JSON data is hard coded (i'd like to add to the list in the future without code changes)
Owen
OwenOP3y ago
I've implemented to this stage - any assistance is appreciated
TheRanger
TheRanger3y ago
is this ur whole config.json or is there more than that?
Owen
OwenOP3y ago
There is more, one moment
TheRanger
TheRanger3y ago
not asking for this
Owen
OwenOP3y ago
Would you want a sample JSON? Sorry, was getting there
TheRanger
TheRanger3y ago
as long as "image_asset_urls" is inside the root of the json, it will work
Owen
OwenOP3y ago
{
"console_title": "Zeron Discord Bot",
"embed_title": "Zeron Developments Automated Checkout",
"bot_prefix": "?",
"bot_token": "0",
"guild_id": 0,
"notification_channel_id": 0,
"ticket_identifer_string": "ticket-",
"order_timeout_minutes": 15,
"log_limit": 25,
"image_asset_urls": [

{
"bot_icon":"test.com"
}

],
"ftp_info": {
"username": "",
"password": "",
"ip_address": "",
"access_url": ""
}
}
{
"console_title": "Zeron Discord Bot",
"embed_title": "Zeron Developments Automated Checkout",
"bot_prefix": "?",
"bot_token": "0",
"guild_id": 0,
"notification_channel_id": 0,
"ticket_identifer_string": "ticket-",
"order_timeout_minutes": 15,
"log_limit": 25,
"image_asset_urls": [

{
"bot_icon":"test.com"
}

],
"ftp_info": {
"username": "",
"password": "",
"ip_address": "",
"access_url": ""
}
}
TheRanger
TheRanger3y ago
ok so what exactly isnt working?
Owen
OwenOP3y ago
How would I call for both the name of the json value (Ex: bot_icon) and the url? I should be able to call for the name value aswell Considering they will be dynamic
TheRanger
TheRanger3y ago
you want to put them into a dictionary?
Owen
OwenOP3y ago
yeah correct, originally I tried a keyvaluepair above but had no luck apologies for my poor explanation
TheRanger
TheRanger3y ago
never tried keyvaluepair but dictionary works
public class Root
{
public List<Dictionary<string, string>> image_asset_urls { get; set; }
}
public class Root
{
public List<Dictionary<string, string>> image_asset_urls { get; set; }
}
after all, Dictionary is a collection of KeyValuePair ah wait
Owen
OwenOP3y ago
Awesome, assuming i'd place
[JsonProperty("image_asset_urls")]
[JsonProperty("image_asset_urls")]
above the Dictionary line also? roger
TheRanger
TheRanger3y ago
its an array, let me fix it
Owen
OwenOP3y ago
👌 Appreciate it
TheRanger
TheRanger3y ago
code edited, not sure if it will work
Owen
OwenOP3y ago
Will give it a shot, thank you
TheRanger
TheRanger3y ago
works fine on my end
Owen
OwenOP3y ago
One more for you, what would the best way to call this be? Previously I used LINQ, unsure what changes would be required here
Owen
OwenOP3y ago
Thanks a bunch for this Very appreciative
TheRanger
TheRanger3y ago
what does the error message say? i have no idea what the type of i and Keys are
Owen
OwenOP3y ago
Owen
OwenOP3y ago
Need to figure out how to filter the keys in the collection to find the correct key, then pull the value ideally Essentially looking to pull any URL from the JSON data using the key value associated with it
TheRanger
TheRanger3y ago
ah i think i see what ur trying to do ur trying to get the value of "bot_icon" ?
Owen
OwenOP3y ago
Sweet, this way I can keep all images external for easy updates. Correct, and if the value is found I want the url associated with bot_icon
TheRanger
TheRanger3y ago
what if you have multiple bot_icons in your List ?
Owen
OwenOP3y ago
I don't see it happening. Each entry in the JSON list would be unique
TheRanger
TheRanger3y ago
will it always be the first element in the list?
Owen
OwenOP3y ago
No It would be changed in position often
TheRanger
TheRanger3y ago
well this is one way of doing it
IconUrl = myDeserializedClass.image_asset_urls.First(dic => dic.ContainsKey("bot_icon"))["bot_icon"];
IconUrl = myDeserializedClass.image_asset_urls.First(dic => dic.ContainsKey("bot_icon"))["bot_icon"];
but there is probably a better way i have to think/remember of but i would suggest to make a method in the Root class to return it cleaner, and avoid repeating code in different places
Owen
OwenOP3y ago
Thanks, i'll implement this ASAP Working!! Thanks a tone. Will leave this open incase you or someone else stumbles across a better way of doing this.
TheRanger
TheRanger3y ago
i already did, 1 sec
Owen
OwenOP3y ago
You're a machine 😛
TheRanger
TheRanger3y ago
public class Root
{
public List<Dictionary<string, string>> image_asset_urls { get; set; }

public string GetValue(string key)
{
foreach(var image in image_asset_urls)
{
if (image.ContainsKey(key))
{
return image[key];
}
}

return null;
}
}
public class Root
{
public List<Dictionary<string, string>> image_asset_urls { get; set; }

public string GetValue(string key)
{
foreach(var image in image_asset_urls)
{
if (image.ContainsKey(key))
{
return image[key];
}
}

return null;
}
}
then u just do IconUrl = config.GetValue("bot_icon");
Owen
OwenOP3y ago
Similar to what I had in mind, great stuff Thanks a lot my friend
Accord
Accord3y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server