System.NotSupportedException: 不支持对 'System.DateOnly' 实例进行序列化和反序列化。

19

我正在使用.NET 6,ASP.NET Core Web API 6。

enter image description here

数据库 PostgreSQL 15。

DROP TABLE IF EXISTS account_object;
CREATE TABLE account_object
(
    id                             uuid DEFAULT uuid_generate_v4 () 
    birth_date                     date,
   
    created                        timestamp with time zone     not null,
    tenant_id                      character varying(36)
);

模型

using System;
using System.Collections.Generic;

namespace acc.Models
{
   
    public partial class AccountObject
    {
        public Guid Id { get; set; }
     
     
        public DateOnly? BirthDate { get; set; }
       
        public DateTime Created { get; set; }
        public string? TenantId { get; set; }        
    }
}

控制器

using acc.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace acc.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountObjectController : ControllerBase
    {
        private readonly ILogger<AccountObjectController> _logger;
        private readonly acc200Context _db;

        public AccountObjectController(ILogger<AccountObjectController> logger, acc200Context acc200Context)
        {
            _logger = logger;
            _db = acc200Context;
        }

        [HttpGet("{tenant_id}")]
        public IEnumerable<AccountObject> Get(string tenant_id)
        {
            return _db.AccountObjects.Where(x => x.TenantId == tenant_id).ToArray();
        }

    }
}

错误

System.NotSupportedException: Serialization and deserialization of 'System.DateOnly' instances are not supported. The unsupported member type is located on type 'System.Nullable`1[System.DateOnly]'. Path: $.BirthDate.
 ---> System.NotSupportedException: Serialization and deserialization of 'System.DateOnly' instances are not supported.
   at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter`1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
   at System.Text.Json.Serialization.Converters.NullableConverter`1.Write(Utf8JsonWriter writer, Nullable`1 value, JsonSerializerOptions options)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.ArrayConverter`2.OnWriteResume(Utf8JsonWriter writer, TElement[] array, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& state, NotSupportedException ex)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at ...

图片 https://i.imgur.com/tb8uj13.png

如何修复?

3个回答

38
如果您使用的是.NET 7,此功能已添加,您无需更改任何内容。
请参见链接中的源生成改进https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-7/
如果您使用的是.NET 6,请实现以下代码:
是的,DateOnlyTimeOnly序列化目前不受支持。有一种解决方法。
public sealed class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
    public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateOnly.FromDateTime(reader.GetDateTime());
    }

    public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
    {
        var isoDate = value.ToString("O");
        writer.WriteStringValue(isoDate);
    }
}

请确保您已添加新的转换器

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      services.AddControllers()
            .AddJsonOptions(options =>
            {
               options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
            });

      // ...
   }
}

是的!这确实很好用,特别感谢您为.NET Core 6.0提供的解决方案! - S.H.
1
我的应用程序NET 6(+Startup),我已经按照这里描述的方式添加了类和调用,但是当我执行obj = JsonSerializer.Deserialize<myClass>(json_str, options)时,我收到了相同的异常。如何修复? - undefined
是DateOnly异常吗?还是其他什么东西? - undefined

3

如果您正在使用较新版本的.NET Core,例如.NET 7,则只需更新System.Text.Json到最新版本,无需额外的转换器即可使一切正常。


我已将我的Web API从.NET 6升级到.NET 7,而且它可以直接使用。太棒了! - Kevy Granero
你也可以在.NET 6上添加最新的NuGet包System.Text.Json。版本7.0.3对我来说很好用。 - undefined

1

这个很好用。

请注意,如果您正在使用较新版本的.NET Core(没有Startup),则可以将以下内容添加到Program.cs中:

 builder.Services.AddControllers()
                .AddJsonOptions(options =>
                {
                    options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
                });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接