Simple Deserialization of JSON from a File in C#

I have worked on more than a few projects that require me to serialize and deserialize JSON. Usually, I’m calling a service that returns JSON, and I need to build a C# model to match it. Then I have to test the model, sometimes it works, sometimes not. I make some minor tweaks are needed to the model. Recently I had to change a Guid type to a string, because, in a small percentage of the requests, the GUID field really contained a URL!

To test out my model I try to deserialize some sample JSON into the model. One way is to create a string in the source code that represents the JSON, but this can be a pain because there is a lot of escaping to do.

The easier way is to create a JSON file and deserialize it, but I often forget how to do this. So this post is mainly for my future self.

Creating the C# model

There are a few ways to create the model from the JSON -

  • Do it manually - fine for very simple models, but error prone for anything beyond that.
  • Use a tool like quicktype. It lets you specify namespace, class name, and the serializer (Newtonsoft or System.Text.Json).
  • Use the Visual Studio Code extension https://marketplace.visualstudio.com/items?itemName=doggy8088.quicktype-refresh. To use System.Text.Json you need to specify the language as C# (System.Text.Json).
  • Rider has a paste JSON as C# classes feature under the Edit -> Paste -> Paste Special: JSON as Classes
  • Visual Studio has a paste JSON as C# classes feature under the Edit -> Paste Special -> Paste JSON as Classes

Reading the JSON file

In the csproj file, add the following line to copy the JSON file to the output directory (easier than worrying about full paths).

<ItemGroup>
  <None Update="*.json">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
</ItemGroup> 

In the Program.cs file, add the required using statements, and configure the JsonSerializerOptions to support enums, conversion of strings to numbers, case insensitivity, and any other options you need.

using System.Text.Json;
using System.Text.Json.Serialization;

var options = new JsonSerializerOptions
{
    Converters = 
    {
         new JsonStringEnumConverter() 
    },
    NumberHandling = JsonNumberHandling.AllowReadingFromString,
    PropertyNameCaseInsensitive = true
};

Here are two simple ways to read the C# from a file. You should also consider using source generators, but I’m not going to cover that here.

// option 1, read the JSON file into a string
string json = File.ReadAllText("people.json");
People peopleFromJsonString = JsonSerializer.Deserialize<People>(json, options);

// option 2, read the JSON from a stream
People peopleFromJsonStream;
using (FileStream jsonStream = new FileStream("people.json", FileMode.Open, FileAccess.Read))
{
    peopleFromJsonStream = await JsonSerializer.DeserializeAsync<People>(jsonStream, options);
}

That’s it. I hope this helps someone else.

comments powered by Disqus

Related