System.Text.Json (and Json.NET) only serializes byte arrays as Base64, so if you declare your Data
as some other collection or enumerable of bytes (but not object
) it will be serialized as a JSON array, e.g:
public class MyModel
{
public int Id { get; set; }
public IEnumerable<byte>? Data { get; set; }
}
When serialized via:
MyModel myObject = new MyModel
{
Id = 1,
Data = new byte[] { 0x01, 0x02, 0x03 }
};
string json = JsonSerializer.Serialize(myObject, options);
Results in:
{"Id":1,"Data":[1,2,3]}
Demo fiddle #1 here.
Or, if you can't change your model, you could introduce a JsonConverter<byte>
that round-trips byte []
values as an array:
public class ByteArrayConverter : JsonConverter<byte []>
{
public override void Write(Utf8JsonWriter writer, byte [] value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, value.AsEnumerable());
public override byte []? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
reader.TokenType switch
{
JsonTokenType.String => reader.GetBytesFromBase64(),
JsonTokenType.StartArray => JsonSerializer.Deserialize<List<byte>>(ref reader)!.ToArray(),
JsonTokenType.Null => null,
_ => throw new JsonException(),
};
}
And serialize like so:
MyModel myObject = new MyModel
{
Id = 1,
Data = new byte[] { 0x01, 0x02, 0x03 }
};
var options = new JsonSerializerOptions { Converters = { new ByteArrayConverter() } };
string json = JsonSerializer.Serialize(myObject, options);
And get the same result.
Demo fiddle #2 here.
Notes: