0

I have a C# project in visual studio and I am using JSON.net, I have a JSON file with 5 objects in it. I want that when I click a button, specific data like "name" and "description" from the 5 objects appear in a textbox.

I don't know what methods to use so I can access the JSON file and grab the data in it.

I read online that JSON is just a way to format data and that if I am doing to do something like a query I should use a database.

This is the JSON file:

{
   "Fighter Features":{
      "Fighting Style (Archery)":{
         "name":"Fighting Style (Archery)",
         "Description:":"You gain +2 bonus to attack rolls you make with ranged weapons."
      },
      "Second Wind":{
         "name":"Second Wind",
         "Description:":"Vou have a limited well of stamina that you can draw on to protect Yourself from harm. On your turn, you can use a bonus action to regain hit points equal to ld10 + your fighter leveI."
      },
      "Fighthing Style (Defense)":{
         "name":"Fighting Style (Defense)",
         "Description:":"While you are wearing armor you gain a +1 bonus to AC."
      }
   }
}
croxy
  • 4,082
  • 9
  • 28
  • 46
xChapx
  • 91
  • 1
  • 1
  • 5
  • I've removed your `visual-studio` tag on the basis that this is not a question about the Visual Studio IDE, so the tag was misused. I've also removed the tags from your question title as per [tagging](https://stackoverflow.com/help/tagging) – ProgrammingLlama Sep 04 '18 at 07:16
  • Possible duplicate [Read Json data from text file C#](https://stackoverflow.com/questions/38179819/read-json-data-from-text-file-c-sharp). – SᴇM Sep 04 '18 at 07:20
  • Have you looked at [How can I parse JSON with C#?](https://stackoverflow.com/q/6620165/3744182) or [Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?)](https://stackoverflow.com/q/4749639/3744182) or [Deserialize JSON into C# dynamic object?](https://stackoverflow.com/q/3142495/3744182) and/or [How to auto-generate a C# class file from a JSON object string](https://stackoverflow.com/q/21611674/3744182)? – dbc Sep 04 '18 at 14:11

3 Answers3

1

I would use File.ReadAllText method to get the JSON data in your computer path.

string jsonData= File.ReadAllText("your file path");

then use json.net JsonConvert.DeserializeObject method to Deserialize the json to object.

RootObject jsonObj  = JsonConvert.DeserializeObject<RootObject>(jsonData); 
D-Shih
  • 44,943
  • 6
  • 31
  • 51
0

You can use this. To use this, use Newtonsoft.Json (which can be installed as Nuget package).

public partial class Welcome
{
    [JsonProperty("Fighter Features")]
    public FighterFeatures FighterFeatures { get; set; }
}

public partial class FighterFeatures
{
    [JsonProperty("Fighting Style (Archery)")]
    public FighthingStyleDefense FightingStyleArchery { get; set; }

    [JsonProperty("Second Wind")]
    public FighthingStyleDefense SecondWind { get; set; }

    [JsonProperty("Fighthing Style (Defense)")]
    public FighthingStyleDefense FighthingStyleDefense { get; set; }
}

public partial class FighthingStyleDefense
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("Description:")]
    public string Description { get; set; }
}

public partial class Welcome
{
    public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters = {
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}
Gauravsa
  • 6,330
  • 2
  • 21
  • 30
  • I didn't explain this in the OP, but i plan to have over 100 objects in the JSON file, wouldn't doing what you propose make it more complicated? creating classes for each object. – xChapx Sep 04 '18 at 07:42
0

If I understand you correctly, you want to consume the JSON string like a strongly typed object. In this case, JObject from Json.net is another choice. Basically JObject is a recursive container, you can loop through all properties within it recursively. For example:

void Main()
{
    string nameOfFeature = "Second Wind";
    JObject jObject = JObject.Parse(data)["Fighter Features"] as JObject;
    foreach (JProperty feature in jObject.Properties())
    {
        if (feature.Name == nameOfFeature)
        {
            JObject secondWind = feature.Value as JObject;
            foreach (JProperty fProperty in secondWind.Properties())
            {
                Console.WriteLine (fProperty.Name + ": " + fProperty.Value);
            }
        }
    }
}

If you do not mind to change your Json data structure, a cleaner approach is to create a strongly typed Model which maps the properties of the JSON string, so that you can use DeserializeObject to cast the JSON string to the C# Model you desire. For example:

void Main()
{
    FighterFigure fighterFeature = JsonConvert.DeserializeObject<List<FighterFigure>>(data);
}

class FighterFigure
{
    public string Name { get; set; }
    public Feature Feature { get; set; }
}

class Feature
{
    public string Name { get; set; }
    public string Description { get; set; }
}

static string data = @"
[
    {
        'Name': 'Fighting Style (Archery)',
        'Feature': {
            'name': 'Fighting Style (Archery)',
            'Description': 'You gain +2 bonus to attack rolls you make with ranged weapons.'
        },
    },
    {
        'Name': 'Second Wind',
        'Feature': {
            'name': 'Second Wind',
            'Description': 'You have a limited well of stamina that you can draw on to protect Yourself from harm. On your turn, you can use a bonus action to regain hit points equal to ld10 + your fighter leveI.'
        },
    },
    {
        'Name': 'Fighthing Style (Defense)',
        'Feature': {
            'name': 'Fighthing Style (Defense)',
            'Description': 'While you are wearing armor you gain a +1 bonus to AC.'
        },
    }
]";
Richard Lu
  • 71
  • 5
  • This worked for me, do you think i can do more specifc searches like only printing the feature that haves "Second wind" as a name? – xChapx Sep 04 '18 at 18:51
  • Yes, you can. I've edited my first approach which you can find above. But honestly, unless you just want to quick hack and you can leave the code running forever. Otherwise it is a nightmare to maintain dynamically cast JObject in the future. Creating strongly typed objects for each structure is a more sensible way to manage the code. – Richard Lu Sep 04 '18 at 22:53