-1

I have a large JSON file that I want to load into my project. I want to then search for the name and return the type. Example below:

[
  {
    "Name": "Name1",
    "Type": "TypeA"
  },
  {
    "Name": "Name2",
    "Type": "TypeB"
  }
]

My problem is that I'm not sure what is the best way to do it. Should i be creating an object class and then loading the file into it?

I've been trying to do this by loading it from my resources. I just cant seem to do it, or find any example of others doing this which leads me to believe I'm doing it the wrong way. I've tried as below:

var resourceName = FS.Properties.Resources.types;
dynamic jsonDe = JsonConvert.DeserializeObject<TypeList>(resourceName);

And

dynamic jsonDe = JsonConvert.DeserializeObject<TypeList>("FS.Resources.types.json");

Any advice would be very welcome. Thanks

SamCodeBad
  • 231
  • 5
  • 10

4 Answers4

3

A way to do this is to deserialize the Json file and store it in a data-class. When the Json file is converted to a list of data-class objects that holds the information, it is possible to use Linq to search for a given value of a property.

See the following link for deserializing a JSON file Deserialize Json From File.

The Linq query would look something like beneath.

arrayList.where(w => w.propertyName == "value of string").select(s => s.propertyName).

It is possible to retrieve a list of matching properties using the .ToList() or if you want a single property .First().

Note that the .First() throws an exception when no matching values could be found. It's possible to use .FirstOrDefault(), this returns a null value there were no matching values.

When using the .FirstOrDefault() method you can add a null check displaying a message if the value you were looking for was found.

M.B.
  • 997
  • 3
  • 11
  • 25
3

From here: How to read embedded resource text file

You can use the Assembly.GetManifestResourceStream Method:

Add the following usings using System.IO; using System.Reflection;

Set property of relevant file: Parameter Build Action with value Embedded Resource

Use the following code

var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyCompany.MyProduct.MyFile.txt";

using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
    string result = reader.ReadToEnd();
}

resourceName is the name of one of the resources embedded in assembly. For example, if you embed a text file named "MyFile.txt" that is placed in the root of a project with default namespace "MyCompany.MyProduct", then resourceName is "MyCompany.MyProduct.MyFile.txt". You can get a list of all resources in an assembly using the Assembly.GetManifestResourceNames Method.

A no brainer astute to get the resourceName from the file name only (by pass the namespace stuff):

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("YourFileName.txt"));

After that you can make use of this or this (suggested by users previously) to Deserialize your values.

Dimitri
  • 1,185
  • 2
  • 15
  • 37
2

I think this is the cleanest and most understandable solution possible:

public class Program
{
  public class MappedObject
  {
    public string Name { get; set; }
    public string Type { get; set; }
  }

  public static void Main(string[] args)
  {
    // search query
    string searchFor = "Name1";
    // our json
    string jsonData = "[{\"Name\": \"Name1\",\"Type\": \"TypeA\"},{\"Name\": \"Name2\",\"Type\": \"TypeB\"}]";
    // I'm mapping the json string into a list of MappedObject (s)
    List<MappedObject> mappedObjects = JsonConvert.DeserializeObject<List<MappedObject>>(jsonData);

    // I'm looping through this list to find the MappedObject
    // that matches the searchFor search query string
    foreach (MappedObject obj in mappedObjects)
    {
      if (obj.Name == searchFor)
      {
        // when I find it, I'll print the Type property
        Console.WriteLine(obj.Type);
      }
    }

    Console.ReadLine();
  }
}

If you want to read the json from an external resource, like a .json file you could do this:

public class Program
{
  public class MappedObject
  {
    public string Name { get; set; }
    public string Type { get; set; }
  }

  public static void Main(string[] args)
  {
    // search query
    string searchFor = "Name1";

    using (StreamReader r = new StreamReader("file.json"))
    {
      // our json read from file.json
      string jsonData = r.ReadToEnd();
      // I'm mapping the json string into a list of MappedObject (s)
      List<MappedObject> mappedObjects = JsonConvert.DeserializeObject<List<MappedObject>>(jsonData);

      // I'm looping through this list to find the MappedObject
      // that matches the searchFor search query string
      foreach (MappedObject obj in mappedObjects)
      {
        if (obj.Name == searchFor)
        {
          // when I find it, I'll print the Type property
          Console.WriteLine(obj.Type);
        }
      }
    }

    Console.ReadLine();
  }
}
Dave
  • 1,912
  • 4
  • 16
  • 34
1

Declaring a class to mimic your JSON structure is an option:

sealed class MyType
{
    public string Name { get; set; }
    public string Type { get; set; }
}

Then you will be able to deserialize it in a typed list and filter according to a given name

private static string FindType(string json, string name)
{
    return JsonConvert.DeserializeObject<List<MyType>>(json)
                      .SingleOrDefault(nt => nt.Name == name)?
                      .Type ?? "No type found";
}

Note that this method assess that no record with the given name can be found, in which case it returns a default string.

If you want to use this method with a resource file:

static void Main(string[] args)
{
    Console.WriteLine(FindType(FS.Properties.Resources.types, "Name1")); //prints "Type1
    Console.WriteLine(FindType(FS.Properties.Resources.types, "name1")); //prints "No type found
    Console.ReadKey();
}
Spotted
  • 4,021
  • 17
  • 33