Home > Net >  System.Text.Json.Serialization.JsonConverterAttribute ignored on IOptions<> json classes in .N
System.Text.Json.Serialization.JsonConverterAttribute ignored on IOptions<> json classes in .N

Time:01-10

I have following options class:

public class GpsAndTelemetryOptions
{
    public const string Section = "GpsAndTelemetry";

    [JsonConverter(typeof(TimespanConverter))]
    public TimeSpan RealtimeOffset { get; set; } = 200.Milliseconds();
}

I am initializing whole environment this way:

                var builder = new ConfigurationBuilder()
                    .SetBasePath(configPath)
                    .AddJsonFile("appSettings.json")

                var configuration = builder.Build();
                var services = new ServiceCollection();

.
.
                services.Configure<GpsAndTelemetryOptions>(
                    configuration.GetSection(GpsAndTelemetryOptions.Section));

                var serviceProvider = services.BuildServiceProvider();

Unfortunately while running following piece of code, the JsonConverterAttribute seems to be ignored. (InvalidOperationException "Failed to convert configuration value ... to type TimeSpan")

                var testOptions = (IOptions<GpsAndTelemetryOptions>)serviceProvider.GetService(typeof(IOptions<GpsAndTelemetryOptions>));
                var value = testOptions.Value;

Is it somehow possible to instruct the inner deserializer to use JsonConverter attribute? Is it even supported within the System.Text.Json? I am using this approach in a console application. Is there anything else to be configured?

here just an example of the json config file:

{
    "GpsAndTelemetry":
    {
        "Uri": "tcp.server://any:5555",
        "RealtimeOffset": "0.700"
    }
}

Thank you very much for any hints..

CodePudding user response:

Configuration is not guaranteed to be json, actually there a lot of configuration providers like environment variables, key vaults, xml files, etc, so configuration is treated as key-value pairs with special binder which is not json compatible. You can try work around that (cause configuration binder does not seem to be very extensible) by changing the property type to int (and it's meaning) and converting in the code when used or via some kind of manual binding (via IConfigureOptions<TOptions> for example). Or just provide timespan in D.HH:mm:nn format (i.e. days, hours, minutes and seconds).

  • Related