Serialize byte array in JSON.NET without $type

6.3k Views Asked by At

I would like to serialize all my contract with $type reference using TypeNameHandling.Objects. However when using this flag, all byte arrays (byte[]) are serialized using $value+$type. I still want Base64 encoding but without $type. For example, for the following contract:

class MyClass
{
  public byte[] MyBinaryProperty {get;set;}
}

I get:

{
  "$type": "MyLib.MyClass, MyAssembly",
  "MyBinaryProperty": {
    "$type": "System.Byte[], mscorlib",
    "$value": "VGVzdGluZw=="
  }
}

I want:

{
  "$type": "MyLib.MyClass, MyAssembly",
  "MyBinaryProperty": "VGVzdGluZw=="
}

Is it possible to serialize all objects via JSON.NET with $type excluding byte arrays? Can I do this without adding any attributes to the contracts (i.e. I want to only alter serializer settings).

1

There are 1 best solutions below

1
On BEST ANSWER

One way to fix this would be to use a custom converter for byte[]:

public class ByteArrayConverter : JsonConverter
{
    public override object ReadJson(
        JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(
        JsonWriter writer,
        object value,
        JsonSerializer serializer)
    {
        string base64String = Convert.ToBase64String((byte[])value);

        serializer.Serialize(writer, base64String);
    }    

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type t)
    {
        return typeof(byte[]).IsAssignableFrom(t);
    }
}

This way you're overriding how byte[] gets serialized and ultimately passing the serializer a string instead of a byte array.

Here's how you'd use it:

string serialized = JsonConvert.SerializeObject(mc, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,
    Formatting = Newtonsoft.Json.Formatting.Indented,
    Converters = new[] { new ByteArrayConverter() }
});

Example output:

{
  "$type": "UserQuery+MyClass, query_fajhpy",
  "MyBinaryProperty": "AQIDBA=="
}

Example: https://dotnetfiddle.net/iDEPIT