常见报错“cannot access a disposed object”源于手动管理流生命周期不当;应让jsonserializer接管流或用using确保自动释放,中小文件优先用file.readalltext。

读取 JSON 文件时 JsonSerializer.Deserialize 报错“Cannot access a disposed object”
常见于用 FileStream 或 StreamReader 手动打开文件后,没注意流生命周期。System.Text.Json 默认会读完就关闭流(尤其在 DeserializeAsync 场景下),但如果你自己 new 了流又传给它,再手动调 .Dispose() 就容易触发这个错误。
正确做法是让 JsonSerializer 完全接管流,或明确控制作用域:
- 用
File.ReadAllText+JsonSerializer.Deserialize<t></t>最省心,适合中小文件(string在内存中,无流管理风险) - 必须用流时,用
using var stream = File.OpenRead("data.json");,然后直接传stream给Deserialize<t></t>—— 不要再额外.Dispose() - 异步读取务必配对:用
DeserializeAsync<t></t>就别用同步的ReadToEnd,否则流位置错乱
JsonSerializerOptions 中 PropertyNameCaseInsensitive 和 WriteIndented 的实际影响
这两个配置看似简单,但误用会导致序列化/反序列化失败或性能浪费。
-
PropertyNameCaseInsensitive = true是反序列化时才起作用(读 JSON 到对象),对写入无影响;它会让字段名匹配忽略大小写,但前提是类里字段名本身能覆盖——比如 JSON 有"userName",而 C# 类写的是public string Username { get; set; },这个选项才能兜住;如果类里是public string name { get; set; },它仍然不匹配 -
WriteIndented = true只影响输出格式(加缩进换行),但会显著增大字符串体积,调试时开它没问题,生产日志或网络传输中建议关掉 - 如果要复用
JsonSerializerOptions实例,记得设为static readonly—— 它不是线程安全的,但只读配置可共享;每次 new 一个反而浪费
处理日期字段时 DateTime 格式不一致导致反序列化失败
JSON 里日期常以 "2024-05-12T10:30:00Z" 或 "2024-05-12" 形式出现,而 C# 默认只认 ISO 8601 带时区的完整格式。遇到只有日期、或带中文“年月日”的字符串,JsonSerializer 直接抛 JsonException。
- 最稳方案:把字段类型改成
string,自己用DateTime.TryParse解析,留出容错空间 - 若坚持用
DateTime,需自定义转换器:JsonConverter<datetime></datetime>,重写Read方法,支持多种格式(如先试TryParseExact几种常见模板) - 别依赖
JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())来处理日期——它只管枚举,不碰DateTime
写入 JSON 文件时 File.WriteAllText 和 StreamWriter 的选择差异
看起来都能写,但编码和异常行为不同,直接影响文件能否被其他系统(比如前端 JS)正常读取。
-
File.WriteAllText("a.json", json)默认用 UTF-8 无 BOM 编码,安全通用;但如果json字符串本身含 BOM(比如从某 API 读来的),它不会自动 strip,可能造成解析失败 -
new StreamWriter("a.json", append: false) { AutoFlush = true }更底层,但你要手动指定Encoding.UTF8(否则可能用系统默认 ANSI),且忘记.Close()或using会导致文件句柄残留 - 推荐组合:
File.WriteAllText("data.json", JsonSerializer.Serialize(data, options), Encoding.UTF8)—— 显式指定编码,避免隐式转换歧义
C# 读写 JSON 看似只是两三个函数的事,但流生命周期、编码隐式转换、日期格式容忍度这些点,一旦漏掉一个,就会卡在“明明代码跑通却读不出数据”的状态里。尤其是跨团队协作时,对方给的 JSON 格式稍有偏差,问题就藏得特别深。










