Hi Friends.
In last week’s article, we briefly touched on how JSON can be tricky to include in unit test code because of conflicting interpretations of the double quote character ("
). In this article we’ll expand on the three approaches mentioned to work around the issue and show examples of how we might use each tactic.
JSON as a C# string
In each example, we’ll be expressing the following JSON object in a C# string. While real world data is likely to be more complex than this (with arrays and nested objects), the underlying concept of representing the data is the same.
{
"Property1": "Value1",
"Property2": "Value2"
}
1. Minified and Escaped
The simplest way to represent JSON in a C# string is to minify it and escape the double quotes. There are many tools available to help with this process; I use the Uglify and Escape commands in the vscode-json extension for Visual Studio Code.
var json =
"{\"Property1\":\"Value1\",\"Property2\":\"Value2\"}";
By minifying the data, we don’t have to worry about multi-line C# strings, new-line terminators, or their (Windows/Unix style) format when doing string comparisons. Unfortunately, data presented in this way is difficult to read, and can make visual comparisons against subtly different data even more difficult. To make things a little easier, we can use string concatenation to spread the JSON across multiple lines without altering the data.
var json = "{" +
"\"Property1\":\"Value1\"," +
"\"Property2\":\"Value2\"" +
"}";
2. Using Verbatim String Literals
Using string concatenation to distribute the JSON across multiple lines helps with readability. But our data is still visually different as it contains escape sequences and concatenation operators. We can tidy things up a little by using verbatim string literals. By prefixing strings with @
we gain two new possibilities.
Firstly, we can create multi-line string values. While this introduces line terminators into our strings, these can be removed by minifying the data before usage/comparison. Alternatively, we can also use String.ReplaceLineEndings to normalise the line endings in our strings.
Secondly, we no longer need to create escape sequences for the JSON double quotes. We still need to indicate that they’re part of the data, but we can instead do this via a method that makes the result easier to read: wrapping the parts of the string including double quotes in double quotes.
This might sound complicated, so let’s look at an example. In the following code, "Property1"
is part of the JSON data; we therefore wrap it inside double quotes, resulting in ""Property1""
. The same applies to also to "Value1"
, "Property2"
, and "Value2"
.
var json = @"{
""Property1"": ""Value1"",
""Property2"": ""Value2""
}";
3. Using Raw String Literals
When working in a C#11/.NET7 (or greater) project, we have one more option: the raw string literal. We declare these in a similar way to Markdown fenced code blocks but with double quotes instead of backticks (`
). In other words, raw string literals start and end with a series of three double quote characters. (You can also use more than three as long as the start and end sequences match in length.)
We can see in the following example that the data is even cleaner than when expressed using verbatim string literals. There’s no need to explicitly mark double quotes that are part of the data: everything within the start and end sequences of the raw string literal is considered part of the string.
var json = """
{
"Property1": "Value1",
"Property2": "Value2"
}
""";
In addition to making things easier to read, raw string literals have one further advantage over verbatim string literals. In the previous example, our JSON is indented by four spaces. However, because the ending series of three double quote characters is also indented by four spaces, those four space characters are removed on each line from the value of the string. In other words, it’s possible to set the “left margin” by positioning the closing double quote sequence accordingly.
Summary
When expressing JSON in C#, double quotes in the data need to be interpreted correctly. You can do this in one of three ways, each affecting human readability.
The simplest way is to minify your data and add escape sequences for the double quotes that are part of your data. But as this can make it difficult to read, you may prefer to use a verbatim string literal.
By prefixing string declarations with @
you can create multi-line strings. This, combined with an alternative to using escape sequences for double quotes can make your code cleaner.
However, you might prefer to use a raw string literal if your project supports it. This will give you the most flexibility and let you include double quote characters in your data without explicitly marking them as such.
Thanks for reading!
This article is from my newsletter. If you found it useful, please consider subscribing. You’ll get more articles like this delivered straight to your inbox (once per week), plus bonus developer tips too!
Top comments (2)
How about resource file?
Hi deexter
That’s a good point – especially as one of my previous articles was about using resource files.
The only thing with resource files is that they require a bit more overhead to incorporate (at the very least they require a new file). I’d suggest using the best approach for the situation - if there’s a lot of JSON or it’s complex, it makes sense to use one. If only one test in a fixture needs a small object encoded as JSON, the overhead might result in more work than necessary.
After mentioning these ways of declaring strings in an earlier article, I thought it might be useful to write this one to give a bit more detail on each style and give examples. That way, you can use the best tool for the job.