I am trying to serialize and deserialize System.Diagnostics.ActivityContext
struct.
According to documentation How to use immutable types and non-public accessors with System.Text.Json I need to add [JsonConstructor]
attribute to
struct constructor, but as struct is defined in standard library I can't do that.
Is there any other way?
Or do I need to write custom converter for struct ActivityContext
as I have done for its properties ActivityTraceId
and ActivitySpanId
?
How would that look? Do I need to write whole deserialization logic to all properties?
Sample code:
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
ActivityContext testContext = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);
Console.WriteLine(testContext.TraceId);
string? serializedActivityContext = JsonSerializer.Serialize(testContext, new JsonSerializerOptions()
{
Converters = { new ActivityTraceIdJsonConverter(), new ActivitySpanIdJsonConverter()}
});
Console.WriteLine(serializedActivityContext);
ActivityContext deserializedActivityContext = JsonSerializer.Deserialize<ActivityContext>(serializedActivityContext, new JsonSerializerOptions()
{
Converters = { new ActivityTraceIdJsonConverter(), new ActivitySpanIdJsonConverter()}
});
Console.WriteLine(deserializedActivityContext.TraceId);
public class ActivityTraceIdJsonConverter : JsonConverter<ActivityTraceId>
{
public override ActivityTraceId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> ActivityTraceId.CreateFromString(reader.GetString());
public override void Write(Utf8JsonWriter writer, ActivityTraceId value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString());
}
public class ActivitySpanIdJsonConverter : JsonConverter<ActivitySpanId>
{
public override ActivitySpanId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> ActivitySpanId.CreateFromString(reader.GetString());
public override void Write(Utf8JsonWriter writer, ActivitySpanId value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString());
}
Sample output:
5ac8dcec05989c8d455955f73ecb2560
{"TraceId":"5ac8dcec05989c8d455955f73ecb2560","SpanId":"96d3440ed8eff463","TraceFlags":0,"TraceState":null,"IsRemote":false}
00000000000000000000000000000000
P.S. not a real world problem. Was just playing with OpenTelemetry context propagation and got curious how would that look with simple json serialazition and got stuck on deserializing struct.