While you can use string interpolation to manually create well-formed JSON, you should not. Instead, in .NET Core 3.1 and later, use the built-in System.Text.Json to generate JSON:
public static string MyMethod(string abc, int pqr) =>
System.Text.Json.JsonSerializer.Serialize(new [] { new { Key = abc, Value = pqr } });
Demo .NET Core fiddle here.
In earlier versions use Json.NET or DataContractJsonSerializer
or even JavaScriptSerializer
as detailed in How do I turn a C# object into a JSON string in .NET?, e.g.:
public static partial class DataContractJsonSerializerHelper
{
public static string ToJson<T>(this T obj, DataContractJsonSerializerSettings settings = null)
{
var serializer = new DataContractJsonSerializer(obj == null ? typeof(T) : obj.GetType(), settings);
using (var memory = new MemoryStream())
{
serializer.WriteObject(memory, obj);
memory.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(memory))
return reader.ReadToEnd();
}
}
}
public static string MyMethod(string abc, int pqr) =>
new [] { new Dictionary<string, object>() { { "Key", abc }, { "Value", pqr } } }
.ToJson(new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true });
Demo fiddle #2 here.
That being said, if you do want to use string interpolation to manually emit JSON, you must correctly handle the following to avoid creating malformed JSON:
As noted in comments by Jeroen Mostert, C# verbatim string literals require embedded double quotes to be doubled up like so:
$@"[{{""Key"":""{abc}"",""Value"": {pqr} }}]";
Keep in mind that it's easy to confuse C# string literal escaping (which is evaluated at compile time) with JSON string escaping (which is required at runtime.) As you write your C# code you will likely need to be typing both.
JSON numeric values must be formatted using the invariant culture to ensure that the decimal separator and negative sign used conform to JSON RFC 8259, so you must use either FormattableString
or String.Create(CultureInfo.InvariantCulture, DefaultInterpolatedStringHandler)
:
String.Create(CultureInfo.InvariantCulture,
$@"[{{""Key"":""{abc}"",""Value"": {pqr} }}]");
See Culture-specific formatting for details.
As stated in RFC 8259, certain characters in JSON string literals must be escaped:
All Unicode characters may be placed within the quotation marks, except for the characters that MUST be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F).
You will need to do this yourself to your abc
string.
Putting all this together, you must still create a method for serializing a string to JSON such as the following:
public static class JsonExtensions
{
static Dictionary<char, string> GetMandatoryEscapes()
{
// Standard escapes from https://www.json.org/json-en.html
var fixedEscapes = new KeyValuePair<char, string> []
{
new('\\', "\\\\"), // Nust be first.
new('"', "\\\""), // This is correct, but System.Text.Json preferrs the longer "\\u0022" for security reasons.
new('/', "\\/"),
new('\b', "\\b"),
new('\f', "\\f"),
new('\n', "\\n"),
new('\r', "\\r"),
new('\t', "\\t"),
};
// Required control escapes from https://www.rfc-editor.org/rfc/rfc8259#section-7
var controlEscapes = Enumerable.Range(0, 0x1F + 1)
.Select(i => (char)i)
.Except(fixedEscapes.Select(p => p.Key))
.Select(c => new KeyValuePair<char, string>(c, @"\u"+((int)c).ToString("X4")));
return fixedEscapes.Concat(controlEscapes).ToDictionary(p => p.Key, p => p.Value);
}
static Dictionary<char, string> Escapes { get; } = GetMandatoryEscapes();
public static string ToJson(this string s) =>
s.Aggregate(new StringBuilder("\""), (sb, c) => Escapes.TryGetValue(c, out var s) ? sb.Append(s) : sb.Append(c)).Append("\"").ToString();
}
And now you can use string interpolation to make well-formed JSON as follows:
public static string MyMethod(string abc, int pqr) =>
String.Create(CultureInfo.InvariantCulture,
$@"[{{""Key"":{abc.ToJson()},""Value"":{pqr} }}]");
Demo fiddle #3 here.
But again, just use a proper JSON serializer.
$@"[{{""Key"":""{abc}"",""Value"": {pqr} }}]"
will work, but this is hardly more readable. Consider using a JSON serializer to avoid string wetwork. – AuditoriumString.Format()
will help and if you write few more functions then you will have a nice short readable code snippet (QuoteJsonString()
,ConvertToJsonKeyValuePair()
and one line LINQ to concat them...) – Thainepublic static string MyMethod(string abc, int pqr) { string p = $$""" [{ "Key":"{{abc}}", "Value": {{pqr}} }] """; return p; }
– Electric