Home > OS >  How can I serialize a literal JSON value with System.Text.Json?
How can I serialize a literal JSON value with System.Text.Json?

Time:11-11

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 of string. It still emits the value as a string.
  • Tried writing a custom JsonConverter, but the Write() method takes in Utf8JsonWriter, 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).

  • Related