Do you have example of using this with a custom JSON converter?
grosch-intl opened this issue · comments
I'm using minimal API with .NET 7 and I wanted to add an attribute to my ID fields so that when the JSON encoding/decoding happens, it automatically runs it through this library. The issue I'm having is that when I call builder.Services.ConfigureHttpJsonOptions
there's not an IServiceProvider
available to pass to the custom converter, meaning it doesn't have access to the injected SqidsEncoder
.
I'm wanting to do something like this:
public sealed class SqidJsonConverter : JsonConverter<int> {
public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
if (reader.GetString() is not string encoded)
throw new JsonException();
return options
.GetServiceProvider()
.GetRequiredService<SqidsEncoder<int>>()
.Decode(encoded)
.FirstOrDefault();
}
public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) {
var sqid = options.GetServiceProvider().GetRequiredService<SqidsEncoder<int>>();
writer.WriteStringValue(sqid.Encode(value));
}
}
How about creating a singleton SqidsEncoder
manually?
var opt = configuration.GetSection("Sqid").Get<CustomSqidOption>();
var encoder = new SqidsEncoder<int>(new SqidsOptions() { MinLength = opt.MinLength, Alphabet = opt.Alphabet });
services.AddSingleton(encoder);
builder.Services.ConfigureHttpJsonOptions(opt =>
{
opt.SerializerOptions.Converters.Add(new SqidJsonConverter(encoder));
});
public sealed class SqidJsonConverter(SqidsEncoder<int> encoder) : JsonConverter<int>
{
public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.GetString() is not string encoded)
throw new JsonException();
return encoder.Decode(encoded).FirstOrDefault();
}
public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
{
writer.WriteStringValue(encoder.Encode(value));
}
}