I have a class in C# 6, something like the following:
public class Foo {
public string Name { get; set; }
public string OtherStuff { get; set; }
}
The OtherStuff
property is a known-valid JSON-encoded string.
I'm trying to return this class from an API method, using the default System.Text.Json
serializer. But I want OtherStuff
to be written out literally, not escaped into a string value.
Things I've tried:
- Looked in
JsonSerializerOptions
for something to do this. - Tried using
System.Text.Json.Nodes.JsonNode
instead ofstring
. It still emits the value as a string. - Tried writing a custom
JsonConverter
, but theWrite()
method takes inUtf8JsonWriter
, which does not appear to have a way to write a string as a literal value, only ways to write a string as a JSON string.
public class LiteralJsonConverter : JsonConverter<string> {
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.GetString();
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
=> writer.WriteStringValue(value); // Can't find a method to write a pre-encoded value
}
I want to avoid having to parse this string from JSON into an object just so I can re-emit it in JSON. It's a JSON string in my database, and the data model is opaque to the API.
Can anyone suggest a solution?
CodePudding user response:
System.Text.Json
supports this starting from version 6, the method is called WriteRawValue:
public class LiteralJsonConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.GetString();
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) =>
writer.WriteRawValue(value);
}
If you are on .NET 6 then it's available by default. Otherwise you can install nuget package System.Text.Json
of version 6 to get access to this functionality (this package supports .NET Standard so can be used even in old .NET 4).
Note that it accepts second parameter: skipInputValidation
, so for even more perfomance, if you are sure what you are writing is valid json - you can skip that and use WriteRawValue(value, true)
.