I have a discord bot that can get a key from a JSON file and return the value depending on the command a user inputs. I want to be able to access complex JSON keys (like "charQuote") and return the associative value (which would be "Video Game character quote here").
{
"characterKey":
{
"charName":"Video Game character name here",
"charQuote": "Video Game character quote here",
"charImageURL": "Video Game character image url here"
}
//I omitted 11 other complex objects that are similar to this one
}
Other answers like:
How do I deserialize a complex JSON object in C# .NET?
How to get Key from nested object with a Json Object and return in array?
how to get the key from json object and convert into an array?
...deserialize and return the complex objects and/or keys as an array. But I want to return a single key value from one complex object.
Here, I have a class that manages a separate JSON file with simple JSON objects:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
namespace discordbot.Modules
{
class Utilities
{
private static Dictionary<string, string> alerts;
private const string File_Path = "json files/alerts.json";
static Utilities()
{
string json = File.ReadAllText(File_Path);
var data = JsonConvert.DeserializeObject<dynamic>(json);
alerts = data.ToObject<Dictionary<string, string>>();
}
public static string GetAlert(string key) //"hello" == key
{
if (alerts.ContainsKey(key))
return alerts[key]; //returns "Hello World" which is the value
return "";
}
This class returns the value from the inputted key. An example asynchronous task method that would use this class would be:
[Command("test")]
public async Task HelloWorldAsync(string hello = "hello")
{
await ReplyAsync(Utilities.GetAlert(hello));
}
And here's the class that associates with the JSON file that contains complex objects.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
namespace discordbot.Modules
{
public static class CharacterUtilities
{
//private static List<Dictionary<string, string>> QuoteAndPicture = new List<Dictionary<string, string>>();
private static Dictionary<string, string> QuoteAndPicture = new Dictionary<string, string>();
private const string File_Path = "json files/quotesandimages.json";
static CharacterUtilities()
{
if(!File.Exists(File_Path))
{
File.WriteAllText(File_Path, "");
}
string json = File.ReadAllText(File_Path);
var data = JsonConvert.DeserializeObject<dynamic>(json);
QuoteAndPicture = data.ToObject<Dictionary<string, string>>();
}
public static string GetQuoteImageName(string key)
{
if (QuoteAndPicture.ContainsKey(key)))
return QuoteAndPicture[key];
return "";
}
Asynchronous method to invoke GetQuoteImageName
[Command("ex")] [RequireOwner]
public async Task CharacterAsync(string characterContext)
{
await ReplyAsync(CharacterUtilities.GetQuoteImageName(characterContext));
}
As it is right now, if I invoke the GetQuoteImageName
method, I get the error: The type initializer for 'discordbot.Modules.CharacterUtilities' threw an exception.
So I'm wondering if there's a similar way to return a singular value from a complex object instead of all the complex values, similar to the first class above.