You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决.NET MAUI中反序列化JSON时的InvalidOperationException?

问题:.NET MAUI银行应用反序列化BankAccount时抛出InvalidOperationException

我正在开发一个.NET MAUI迷你银行应用,点击「登录」或「注册」按钮时会从JSON文件加载客户数据。当Customer没有关联账户时反序列化正常,但添加BankAccount到JSON文件后,反序列化时抛出InvalidOperationException。

错误信息

System.InvalidOperationException
HResult=0x80131509
Message=Each parameter in the deserialization constructor on type 'ReadOnlyBankingSystem.Models.BankAccount' must bind to an object property or field on deserialization. Each parameter name and type must match with a property or field on the object. Fields are only considered when 'JsonSerializerOptions.IncludeFields' is enabled. The name match can be case-insensitive.
Source=System.Text.Json


相关代码

Customer类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.Json.Serialization;

namespace ReadOnlyBankingSystem.Models
{
    public class Customer
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }    
        public string Email { get; set; }
        public string Address { get; set; }
        public DateOnly DateOfBirth { get; set; }

        public ObservableCollection<BankAccount> Accounts { get; set; }

        public Customer(string username, string password, string firstName, string lastName, string email, string address, DateOnly dateOfBirth)
        {
            this.Username = username;
            this.Password = password;
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Email = email;
            this.Address = address;
            this.DateOfBirth = dateOfBirth;
            this.Accounts = new ObservableCollection<BankAccount>();
        }
    }
    
    [JsonSerializable(typeof(Dictionary<string, Customer>))]
    internal sealed partial class CustomerContext : JsonSerializerContext
    {
    }
}

BankAccount类

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.Json.Serialization;

namespace ReadOnlyBankingSystem.Models
{
    public class BankAccount
    {
        [JsonInclude]
        public readonly Guid AccountId;
        [JsonInclude]
        public readonly DateTime DateCreated;
        [JsonInclude]
        public readonly int PIN;
        public decimal Amount { get; set; }
        public ObservableCollection<Transaction> Transactions { get; set; }

        public BankAccount(Guid accountId, DateTime dateCreated, int pin, decimal initialAmount)
        {
            AccountId = accountId;
            DateCreated = dateCreated;
            Amount = initialAmount;
            PIN = pin;
            Transactions = new ObservableCollection<Transaction>();
        }
    }
}

序列化/反序列化函数

public async Task<Dictionary<string, Customer>> ReadFromJsonFile(string filename)
{
    string appDataFilePath = GetAppDataFilePath(filename);
    using var stream = File.OpenRead(appDataFilePath);
    using var reader = new StreamReader(stream);
    var contents = await reader.ReadToEndAsync();
    var customerDictionary = JsonSerializer.Deserialize(contents, CustomerContext.Default.DictionaryStringCustomer);

    return customerDictionary;
}

public async Task WriteToJsonFile(string filename, Dictionary<string, Customer> customerData) 
{
    string appDataFilePath = GetAppDataFilePath(filename);
    using var stream = File.OpenWrite(appDataFilePath);
    using var writer = new StreamWriter(stream);
    var options = new JsonSerializerOptions { WriteIndented = true };
    var contents = JsonSerializer.Serialize(customerData, options);
    await writer.WriteAsync(contents);
}

解决方案

问题根源在于BankAccount的构造函数参数与类中字段/属性不匹配,且反序列化未配置包含字段的选项。具体修复步骤如下:

步骤1:调整BankAccount构造函数参数名

将构造函数中的initialAmount改为amount,让参数名与Amount属性名匹配,保证反序列化时能正确绑定:

public BankAccount(Guid accountId, DateTime dateCreated, int pin, decimal amount)
{
    AccountId = accountId;
    DateCreated = dateCreated;
    Amount = amount;
    PIN = pin;
    Transactions = new ObservableCollection<Transaction>();
}

步骤2:配置JsonSerializerContext启用字段支持

修改CustomerContext,添加JsonSourceGenerationOptionsAttribute开启IncludeFields,并显式添加BankAccount的序列化支持:

[JsonSourceGenerationOptions(IncludeFields = true)]
[JsonSerializable(typeof(Dictionary<string, Customer>))]
[JsonSerializable(typeof(BankAccount))]
internal sealed partial class CustomerContext : JsonSerializerContext
{
}

步骤3:统一序列化与反序列化的配置

在WriteToJsonFile中使用CustomerContext的内置选项,避免序列化和反序列化配置不一致:

public async Task WriteToJsonFile(string filename, Dictionary<string, Customer> customerData) 
{
    string appDataFilePath = GetAppDataFilePath(filename);
    using var stream = File.OpenWrite(appDataFilePath);
    await JsonSerializer.SerializeAsync(stream, customerData, CustomerContext.Default.DictionaryStringCustomer);
}

可选替代方案(无需修改参数名)

如果不想调整构造函数参数名,可以给参数添加JsonPropertyName特性指定对应属性名:

public BankAccount(Guid accountId, DateTime dateCreated, int pin, [JsonPropertyName("Amount")] decimal initialAmount)
{
    AccountId = accountId;
    DateCreated = dateCreated;
    Amount = initialAmount;
    PIN = pin;
    Transactions = new ObservableCollection<Transaction>();
}

注意:如果Transaction类也存在只读字段或构造函数绑定问题,需要执行同样的修复操作。

内容的提问来源于stack exchange,提问作者Arturo Girona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:14:50