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

C#类内嵌套对象序列化为JSON仅输出{}的问题排查与解决

问题分析与解决方案

核心原因

你遇到的appSession被序列化为{}的问题,本质是System.Text.Json的序列化规则限制:

  • 默认仅序列化公共属性(带get/set的成员),不序列化字段(无论公共还是私有);
  • internal修饰的类/成员默认无法被序列化;
  • 反序列化时需要目标类有无参构造函数,否则无法实例化对象。

对照你的代码:

  • appSession中的LinkedSite是公共字段,IUSession是internal字段;
  • ImageUploaderData的workAreaImages是私有字段;
  • WorkingImage的EXIF_filename是私有字段;
  • appSession只有带参数的构造函数,无默认无参构造。

这些都导致序列化器无法读取/写入对象的实际数据,最终输出空对象{}。

分步修复

1. 将字段改为公共属性

把所有需要序列化的字段改成带get/set的公共属性,这是最规范的做法:

修改appSession类:

public class appSession
{
    // 公共属性替代公共字段
    public SiteConnection LinkedSite { get; set; }
    // 若需序列化IUSession,改为public(或后续通过配置选项兼容internal)
    public ImageUploaderData IUSession { get; set; }

    // 添加无参构造函数,用于反序列化
    public appSession() { }

    public appSession(SiteConnection linkedSite)
    {
        LinkedSite = new SiteConnection(linkedSite);
        IUSession = new ImageUploaderData();
    }
}

修改ImageUploaderData类:

// 若需序列化,建议改为public,或保留internal并配置序列化选项
public class ImageUploaderData
{
    // 公共属性替代私有字段
    public List<WorkingImage> WorkAreaImages { get; set; }

    public ImageUploaderData()
    {
        WorkAreaImages = new List<WorkingImage>();
    }
}

修改WorkingImage类:

public class WorkingImage : WorkingFile
{
    public enum TaggingState
    {
        Untagged,
        Issue,
        Tagged
    }

    // 公共属性替代私有字段
    public string EXIF_Filename { get; set; }

    // 保留构造函数,确保反序列化可用
    public WorkingImage() : base()
    {
        selected = false;
    }

    public WorkingImage(string path) : base(path)
    {
        selected = false;
    }
}

2. 配置序列化选项(可选,若需保留internal成员)

如果不想修改类的可见性(比如保留internal类),可以在序列化时配置JsonSerializerOptions,指定包含字段并允许访问非公共成员:

在UserData的Save、Create方法中修改选项:

var options = new JsonSerializerOptions
{
    WriteIndented = true,
    // 包含所有字段(公共/私有/internal)
    IncludeFields = true,
    // 允许反序列化时访问非公共构造函数
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};

3. 优化序列化逻辑(更优实现)

把序列化/反序列化逻辑从UserData中抽离,做成独立工具类,降低耦合性,同时统一配置选项:

public static class JsonStorageHelper
{
    private static readonly JsonSerializerOptions _defaultOptions = new()
    {
        WriteIndented = true,
        IncludeFields = true, // 根据需求选择是否启用
        ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
    };

    public static async Task SaveToFileAsync<T>(T data, string filePath)
    {
        var folder = ApplicationData.Current.LocalFolder;
        var file = await folder.CreateFileAsync(filePath, CreationCollisionOption.ReplaceExisting);
        var json = JsonSerializer.Serialize(data, _defaultOptions);
        await FileIO.WriteTextAsync(file, json);
    }

    public static async Task<T?> LoadFromFileAsync<T>(string filePath)
    {
        var folder = ApplicationData.Current.LocalFolder;
        try
        {
            var file = await folder.GetFileAsync(filePath);
            var json = await FileIO.ReadTextAsync(file);
            return JsonSerializer.Deserialize<T>(json, _defaultOptions);
        }
        catch (FileNotFoundException)
        {
            return default;
        }
    }
}

简化后的UserData类:

public class UserData
{
    public List<appSession> userSessions { get; set; }
    public DatabaseConnection lastDatabaseConnection { get; set; }
    public string temp { get; set; }

    public UserData()
    {
        userSessions = new List<appSession>();
    }

    public async Task SaveAsync()
    {
        await JsonStorageHelper.SaveToFileAsync(this, @"UserData\user.json");
    }

    public static async Task<UserData> LoadOrCreateAsync()
    {
        var data = await JsonStorageHelper.LoadFromFileAsync<UserData>(@"UserData\user.json");
        if (data == null)
        {
            data = new UserData();
            await data.SaveAsync();
        }
        return data;
    }
}

验证修改

修复后,user.json应该能正确输出appSession的内容,示例如下:

{
  "userSessions": [
    {
      "LinkedSite": { /* SiteConnection的具体内容 */ },
      "IUSession": {
        "WorkAreaImages": []
      }
    }
  ],
  "lastDatabaseConnection": null,
  "temp": "test test test"
}

内容的提问来源于stack exchange,提问作者Mark L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 19:50:17