我正在将一个项目更新到.NET 8,一些以前可序列化/可重新序列化的模型类现在引发了此错误:

类型"MyModel"上反序列化构造函数中的每个参数都必须绑定到反序列化上的对象属性或字段.每个参数名称必须与对象上的属性或字段匹配.仅当启用"JsonSerializerFields.IncludeFields"时,才会考虑字段.匹配可能不区分大小写.

我似乎能够停止异常的唯一方法是提供一个无参数构造函数,但我不想这样做.

更新

以下代码用于序列化/反序列化

void Main()
{
    RunTests();  // Call RunTests() or press Alt+Shift+T to initiate testing.
}

public class MyClass
{
    public int Number { get; set; }
    public string Text { get; set; }
    
    public MyClass(int num, string characters)
    {
        Number = num;
        Text = characters;
    }

    // public MyClass() {} Test succeeds with parameterless ctor
}

[Fact] void Test_Xunit() 
{
    var mc = new MyClass(88, "foo");
    
    var s = JsonSerializer.Serialize(mc);
    
    var o = JsonSerializer.Deserialize<MyClass>(s);
}

推荐答案

正如上面的 comments 所指出的,您需要确保构造函数的参数与属性名称匹配.由于序列化器使用属性名称来创建json,因此串化器需要知道这些属性中的哪些属性用于哪个构造函数参数.

因此,像这样更改您的类:

public class MyClass
{
    public int Number { get; set; }
    public string Text { get; set; }
    
    public MyClass(int number, string text) // argument names must match the property names
    {
        Number = number;
        Text = text;
    }
}

比较结果为case insensitive,这样您就可以使用标准命名约定(属性使用大写名称,参数使用大写名称).

作为alternative,您可以添加一个无参数构造函数,并让解串器使用属性设置器来初始化对象:

public class MyClass
{
    public int Number { get; set; }
    public string Text { get; set; }
    
    public MyClass(int num, string characters)
    {
        Number = num;
        Text = characters;
    }

    [JsonConstructor]
    public MyClass()
    {
    }
}

如果属性/参数类型复杂,则需要第二种方法.这意味着如果您的类使用对另一个用户定义类型的引用,那么您需要使用第二种方法.

Csharp相关问答推荐

Should. ThrowAsynock未捕获来自httpClient. GetAsynock()请求的异常

C#编译器会优化表达体成员的重新判断吗?

利用.NET 8中的AddStandardResilienceDeliveries和AddStandardHedgingDeliveries实现Resiliency

Plotly.NET访问互联网时出现异常

获取ASP.NET核心身份认证cookie名称

错误401未授权ASP.NET Core.使用JWT创建身份验证/授权

处理. netstandard2.0项目中HttpClient.SslProtocol的PlatformNotSupportedException问题""

并行令牌更新

如何使用CsvReader获取给定列索引的列标题?

是否可以使用EF—Core进行临时部分更新?

安装附加的. exe与Visual Studio

可为空的泛型属性

如何在C#中从正则表达式中匹配一些数字但排除一些常量(也是数字)

Azure函数-在外部启动类中生成配置时出错

如何在发布NuGet包之前设置命名空间?

在C#中,当输入一个方法/局部函数时,我的IEnumerator被重置/重新创建.为什么?

用于ASP.NET核心的最小扩展坞

如何使用ODP.NET C#设置Oracle会话时间长度限制

当`JToken?`为空时?

将列表转换为带有逗号分隔字符串形式的值的字典