在构造函数参数的类型与具有匹配名称的属性的类型不匹配的情况下,使STJ正确反序列化的最佳方法是什么?

请考虑以下代码示例:

using System.Text.Json;

string data = """
              {
                "Ints": [24, 43, 54, 23]
              }
              """;

var parsed = JsonSerializer.Deserialize<Data>(data)!;

class Data
{
    public Data(IEnumerable<int> ints)
    {
        Ints = ints.ToList().AsReadOnly();
    }

    public IReadOnlyCollection<int> Ints { get; }
}

构造函数参数ints的类型与属性Ints的类型不匹配.这会导致反序列化失败,尽管这个用例看起来非常合理.

反序列化在Newtonsoft上的工作与预期一样,但如果可能的话,我想使用STJ.

例外消息:

System.InvalidOperationException:
Each parameter in the deserialization constructor on type 'Data' must bind to an object property or field on deserialization.
Each parameter name must match with a property or field on the object.
Fields are only considered when 'JsonSerializerOptions.IncludeFields' is enabled.
The match can be case-insensitive.

推荐答案

看看这How to use immutable types and non-public accessors with System.Text.Json份文档吧.一种应对方法是引入JsonConstructor:

class Data
{
    [JsonConstructor()]
    public Data(IReadOnlyCollection<int> ints)
    {
        Ints = ints; // or create the copy.
    }

    public Data(IEnumerable<int> ints)
    {
        Ints = ints.ToList().AsReadOnly();
    }

    public IReadOnlyCollection<int> Ints { get; }
}

或使用带有私有setter和无参数ctor的属性:

class Data
{
    public Data()
    {
        Ints = new int[] { };
    }

    public Data(IEnumerable<int> ints)
    {
        Ints = ints.ToList().AsReadOnly();
    }

    [JsonInclude]
    public IReadOnlyCollection<int> Ints { get; private set; }
}

除此之外,你可以考虑创造一个custom converter.

Csharp相关问答推荐

为什么Microsoft.AspNetCore. htttp.FormFile不实现IDDisposable?

将.NET 8程序集加载到Matlab R2023a中时出现问题

Serilog SQL服务器接收器使用UTC作为时间戳

Microsoft. SQLServer. Types(106.1000.6)在try 从用户定义的类型检索值时引发异常

应该使用哪一个?"_counter += 1 OR互锁增量(ref_counter)"""

Polly使用泛型重试和重试包装函数

Blazor-从数据库内部服务器提取错误

更新产品但丢失产品ASP.NET Core的形象

返回TyedResults.BadRequest<;字符串>;时问题详细信息不起作用

HttpRequestMessage.SetPolicyExecutionContext不会将上下文传递给策略

有没有更好的方法来在CosmosDB上插入非id?

MSTest--将消息直接写入StdOut和使用TestContext有什么不同?

将操作从编辑页重定向到带参数的索引页

为什么我不能从我的异步任务方法中返回异步任务方法?

JsonPath在Newtonsoft.Json';S实现中的赋值

System.NotSupportdException:流不支持读取

ASP.NET MVC数据批注验证组复选框

错误:此版本的Visual Studio无法打开以下项目

工厂类是如何在.NET 8中注册的?

Azure函数正在返回值列表,但该列表在Chrome中显示为空