In ASP.NET Core 3.1 Razor Page pure front end web application I received the below error.

Installed the following packages:

<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="EnumExtensions.System.Text.Json" Version="1.0.0" />
<PackageReference Include="NodaTime" Version="3.0.1" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.0.0" />

Also set this in Startup:

services.AddRazorPages()
  .AddJsonOptions(options =>
  {
      // options.JsonSerializerOptions.PropertyNamingPolicy = null;
      // options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
      // options.JsonSerializerOptions.DictionaryKeyPolicy = null;

      options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverterWithAttributeSupport(null, true, true, true, true));
      //options.JsonSerializerOptions.IgnoreNullValues = true;
      options.JsonSerializerOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
      options.JsonSerializerOptions.Converters.Add(NodaConverters.IntervalConverter);
      options.JsonSerializerOptions.Converters.Add(NodaConverters.InstantConverter);
  })
  .AddRazorPagesOptions(options =>
  {
      options.Conventions.AddPageRoute("/Login", "");
  });

JsonException: The JSON value could not be converted to NodaTime.Instant. Path: $.data[0].created_at | LineNumber: 0 | BytePositionInLine: 261. System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType) System.Text.Json.JsonPropertyInfoNotNullable<TClass, TDeclaredProperty, TRuntimeProperty, TConverter>.OnRead(ref ReadStack state, ref Utf8JsonReader reader) System.Text.Json.JsonPropertyInfo.Read(JsonTokenType tokenType, ref ReadStack state, ref Utf8JsonReader reader) System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack readStack) System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, ref Utf8JsonReader reader) System.Text.Json.JsonSerializer.Deserialize(string json, Type returnType, JsonSerializerOptions options) System.Text.Json.JsonSerializer.Deserialize(string json, JsonSerializerOptions options)

Here's the snippet of data it's trying to deserialize. If I switch from Instant to DateTimeOffset, it works "instantly".

{
    "data": [
        {
            "created_at": "2020-08-09T22:10:26.274672Z",
            "updated_at": "2020-08-13T02:22:02.640871Z",
        }
    ],
    "page": 1,
    "size": 20,
    "count": 1,
    "total": 1,
    "success": true,
    "message": null
}

Note: this JSON data is a result of serialization of an object that does include CreatedAt & UpdatedAt properties of the type (NodaTime)Instant. I confirm it works nicely with an ASP.NET Core 3.1 MVC API application.

Not sure why it's not working.

1

There are 1 answers

0
BRBdot On

JsonSerializerOptions cannot be set at global in the current version of System.Text.Json. This can be resolved by building options right where you need them:

var jsonString = "{\"data\":[{\"id\":\"f606942c-4740-46a7-be6f-66ceb38c530b\",\"created_at\":\"2020-08-09T22:10:26.274672Z\",\"updated_at\":\"2020-08-13T02:22:02.640871Z\"}],\"page\":1,\"size\":20,\"count\":1,\"total\":1,\"success\":true,\"message\":null }";
    
JsonSerializerOptions options = new JsonSerializerOptions();
options.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
options.Converters.Add(new JsonStringEnumConverterWithAttributeSupport(null, true, true, true, true));

var response = JsonSerializer.Deserialize<Response>(jsonString, options);

    
public enum SampleType
{
    TYPE_0,
    TYPE_1
}

public class Sample
{
    [JsonProperty("id")]
    public string Id { get; set; } = System.Guid.NewGuid().ToString();
    [JsonProperty("created_at")]
    public Instant CreatedAt { get; set; }
    [JsonProperty("updated_at")]
    public Instant UpdateAt { get; set; }

    [JsonProperty("type")]
    public SampleType Type { get; set; }
}

public class Response
{
    [JsonProperty("data")]
    public IEnumerable<Sample> Data { get; set; }
    
    [JsonProperty("page")]
    public int Page { get; set; }
    
    [JsonProperty("size")]
    public int Size { get; set; }
    
    [JsonProperty("count")]
    public int Count { get; set; }
    
    [JsonProperty("total")]
    public int Total { get; set; }
    
    [JsonProperty("success")]
    public bool Success { get; set; }

    [JsonProperty("message")]
    public string Message { get; set; }
}