首页 游戏 软件 资讯 排行榜 专题
首页
编程语言
C# JSON序列化完整指南与常见问题解决方法

C# JSON序列化完整指南与常见问题解决方法

热心网友
65
转载
2026-05-06

C# JSON序列化:那些看似“玄学”的问题,其实都有章可循

c#如何序列化JSON_c#序列化JSON常见问题与排错指南

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

在C#里处理JSON,JsonSerializer.SerializeJsonConvert.SerializeObject 这两行代码谁都会写。但真正让人头疼的,往往不是“怎么调”,而是那些藏在类型、配置、时区、命名规则里的细节。它们一旦对不上,轻则字段错位,重则数据丢失。下面这四大高频问题,几乎每个.NET开发者都会踩到。

System.Text.Json 默认驼峰命名、Newtonsoft.DateTime格式异常、字典键被改、long精度丢失是四大高频问题;需分别通过设置PropertyNamingPolicy=null、DateFormatHandling.IsoDateFormat、DefaultContractResolver、long转字符串解决。

System.Text.Json 默认驼峰命名导致字段名被改写

你有没有遇到过这种情况:明明在C#里定义的是 public string UserName { get; set; },序列化出去却变成了 "userName"?先别急着怀疑人生,这通常不是bug,而是特性在起作用。

从.NET 6开始,System.Text.Json 默认启用了 JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase。这个策略尤其在ASP.NET Core Web API中会自动生效,目的是为了迎合前端Ja vaScript社区的命名习惯。

  • 先确认需求:如果你的服务是内部系统,或者主要对接前端,用驼峰命名大概率没问题。但如果是和Ja va、Python等其他后端服务互通,对方很可能期望的是PascalCase(即首字母大写),这时就需要关掉它。
  • 如何关掉:很简单,var options = new JsonSerializerOptions { PropertyNamingPolicy = null }; 就能让命名策略失效。
  • 注意边界:这个设置只影响类的public属性名,默认不影响字典的key。除非你用的是.NET 7及以上版本,并且显式设置了 DictionaryKeyPolicy
  • 别混淆了:全局的 PropertyNamingPolicy 和单个属性上的 [JsonPropertyName("CustomName")] 特性是两回事。后者的优先级更高,可以覆盖全局策略。

Newtonsoft.Json 序列化 DateTime 输出 /Date(1234567890000)/ 格式

如果你还在用Newtonsoft.Json(即Json.NET),可能会发现序列化出来的时间戳长这样:/Date(1234567890000)/。这是库默认使用 Ja vaScriptDateTimeConverter 的结果,一种比较古老的格式。现代的API接口基本已经不认这种格式了,前端解析时要么失败,要么时间错乱。

  • 强制使用ISO标准格式:最直接的解决方法是配置序列化设置:new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat }。这样输出的就是 "2023-10-27T10:30:00Z" 这种通用格式。
  • 时区问题不能只靠配置:如果服务端明确要求UTC时间,千万别只依赖这个配置。务必在序列化前,对DateTime对象调用 .ToUniversalTime()。否则,本地时区的时间会被直接当成UTC时间写进去,造成误解。
  • 自定义格式更稳妥:对于有固定格式要求的场景,可以设置 DateFormatString = "yyyy-MM-dd HH:mm:ss"。但要注意,这个设置只在 DateFormatHandling = DateFormatHandling.Custom 时才会生效。
  • 避免配置冲突:别在同一个属性的头上既标记了 [JsonConverter(typeof(DateTimeConverter))],又在全局配置里配一遍,这样很容易导致行为不一致。

序列化 Dictionary 后键名丢失或全小写

字典序列化后,发现key的名字变了,甚至全变成小写了?别慌,数据没丢,是序列化库的默认策略在“动”你的key。

这里有个关键区别:System.Text.Json 默认会保留字典键的原样;而 Newtonsoft.Json 的行为则严重受 ContractResolver 影响。

  • 检查Newtonsoft的解析器:如果你用了 CamelCasePropertyNamesContractResolver,那要注意了,它不仅会把属性名改成驼峰,字典的key也会被一并改造。
  • 锁死原始键名:在Newtonsoft中,想保持key不变,可以使用默认的解析器:new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }
  • System.Text.Json的版本陷阱:在.NET 6及以后版本,如果你启用了全局的 PropertyNamingPolicy(比如驼峰),那么字典的key也会被影响而改变。这一点在早期版本中是不会发生的,非常容易忽略。
  • 警惕嵌套序列化:如果字典的value是匿名对象或者动态的 JObject,要确保它本身没有被二次序列化。一个常见的坑是:JsonConvert.SerializeObject(new { data = JObject.Parse(json) }),里面的JObject可能已经被处理过一次了。

序列化 long 类型 ID 到前端时精度丢失

这是前后端联调时的一个经典“惨案”。C#里的 long 类型(Int64)最大值可以达到 2^63 - 1,常用于生成雪花ID等大数字。但Ja vaScript的 Number 类型,其最大安全整数是 2^53 - 1。一旦超过这个范围,数字传到前端就会精度丢失,变成一串奇怪的尾数。

  • 根本解法:转成字符串:必须把long类型的值,在序列化阶段就转换成字符串。不要指望前端用 parseInt 去补救,那为时已晚。
  • Newtonsoft的解决方案:推荐编写一个自定义转换器。继承 JsonConverter,然后重写 WriteJson 方法,在里面调用 writer.WriteValue(value.ToString()) 即可。
  • System.Text.Json的解决方案:思路类似,继承 JsonConverter,实现对应的 Write 方法。最后记得在 JsonSerializerOptions 里通过 options.Converters.Add(new LongToStringConverter()) 注册这个转换器。
  • 格式化不是关键:别纠结于用 ToString("D") 还是其他数字格式,只要最终输出的JSON值是带引号的字符串(如 "id": "1234567890123456789"),前端就能无损接收。

最后,还有一个最常被跳过的环节:序列化后的校验。代码跑通了,不代表JSON就对了。在把数据发出去之前,不妨先用 JsonDocument.Parse(json) 快速验证一下结构,或者扔到在线JSON格式化工具里看一眼。很多时候所谓的“序列化失败”,其实是上游数据拼接时字符串就错了,问题根本不在序列化逻辑本身。

来源:https://www.php.cn/faq/2324543.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

怎样在Perplexity中获取特定的JSON Schema定义_描述数据结构并要求生成
AI
怎样在Perplexity中获取特定的JSON Schema定义_描述数据结构并要求生成

如何在Perplexity中实现JSON Schema约束响应:五种实用方法 想要让AI聊天助手Perplexity严格按照你定义的数据结构来输出答案吗?这就像给一个思维活跃的助手一份精确的图纸,要求它按图施工。JSON Schema正是这份图纸,它能明确规定响应中必须包含哪些字段、每个字段是什么类

热心网友
05.06
如何自定义 Go 结构体字段的默认序列化命名规则(JSON/BSON)
编程语言
如何自定义 Go 结构体字段的默认序列化命名规则(JSON/BSON)

如何自定义 Go 结构体字段的默认序列化命名规则(JSON BSON) 在 Go 语言中,结构体字段进行 JSON 和 BSON 序列化时,默认行为是将 PascalCase 转换为 snake_case 或保持原名。开发者无法全局修改这一默认规则,必须通过结构体标签进行显式声明。对于追求高效和整洁

热心网友
05.06
如何自定义 Go 结构体字段的默认 JSON/BSON 字段名映射规则
编程语言
如何自定义 Go 结构体字段的默认 JSON/BSON 字段名映射规则

如何自定义 Go 结构体字段的默认 JSON BSON 字段名映射规则 在 Go 语言开发中,结构体字段的 JSON 和 BSON 序列化默认遵循特定的命名转换规则。然而,这套默认行为往往无法满足项目对统一命名风格(如小写驼峰命名法)的全局需求。开发者要么需要为每个字段手动添加标签,要么就需要借助代

热心网友
05.06
如何优雅处理 JSON 中同一字段时而为对象、时而为数组的 Go 解析难题
编程语言
如何优雅处理 JSON 中同一字段时而为对象、时而为数组的 Go 解析难题

如何优雅处理 JSON 中同一字段时而为对象、时而为数组的 Go 解析难题 在对接不规范 REST API 时,开发者常面临同一 JSON 字段(例如 “line”)在不同响应中动态变化,时而为单个对象,时而为对象数组,导致标准 Go 结构体反序列化失败。本文将深入解析如何通过 json RawMe

热心网友
05.06
如何在 Go 中优雅处理 JSON 字段类型不一致(时而对象、时而数组)的问题
编程语言
如何在 Go 中优雅处理 JSON 字段类型不一致(时而对象、时而数组)的问题

应对JSON字段类型飘忽不定:Go中的灵活解析策略 在对接第三方API时,开发者们常常会遇到一个令人头疼的设计:同一个JSON字段,其数据类型居然会“变脸”。比如,一个名为line的字段,在返回单条记录时是个对象({ }),而在返回多条记录时却摇身一变,成了对象数组([ ])。这种反模式设计

热心网友
05.06

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

POE交换机连接设备后频繁重启原因解析
电脑教程
POE交换机连接设备后频繁重启原因解析

Poe交换机带载后重启:是故障,还是系统在“自救”? 不少朋友遇到过这个头疼的问题:PoE交换机一接上设备就重启。其实,这本质上不是设备坏了,而是供电系统一套精密的自我保护机制在起作用。当负载接入的瞬间,如果系统检测到功耗超标、供电不稳等情况,就会主动触发复位,防止硬件受损。这正是IEEE 802

热心网友
05.06
电饼铛选购指南哪款型号性价比最高
电脑教程
电饼铛选购指南哪款型号性价比最高

高性价比电饼铛:精准匹配、扎实可靠、真正省心 挑选一款高性价比的电饼铛,核心其实很明确:功能要精准匹配你的真实需求,材质工艺必须扎实可靠,细节设计能让你每天用着都省心。它追求的绝不是单纯的便宜或者参数漂亮,而是每一分钱都花在刀刃上。比如,2100W级的稳定火力保证了煎烤效率不打折;0氟不粘涂层配合蜂

热心网友
05.06
红米K30 5G动态壁纸不联网可以使用吗
电脑教程
红米K30 5G动态壁纸不联网可以使用吗

红米K30 5G动态壁纸联网机制全解析 关于红米K30 5G的动态壁纸是否需要一直联网,答案是:完全没必要。这玩意儿用起来其实很“懂事”,它只在你第一次上手和偶尔想换新的时候,才需要网络搭把手。 其背后的逻辑很清晰:手机搭载的MIUI系统,把所有酷炫的动态壁纸资源都放在了小米官方的“云端仓库”里。所

热心网友
05.06
vivo Y35手机桌面时间不显示修复方法
电脑教程
vivo Y35手机桌面时间不显示修复方法

vivo Y35桌面时间不显示?别急,这事儿有解 不少vivo Y35用户可能都遇到过这个情况:一觉醒来,或者换个主题之后,主屏幕上那个熟悉的“时间”不见了。先别急着怀疑手机坏了,事实是,超过八成的类似问题,根源其实很简单——时间组件压根没被“请”上桌面,或者相关的自动设置被无意中关闭了。作为一台搭

热心网友
05.06
英雄联盟手游杰斯新皮肤获取方法与实战评测
游戏攻略
英雄联盟手游杰斯新皮肤获取方法与实战评测

英雄联盟手游杰斯新皮肤外观设计酷炫,充满科技感。技能特效以蓝色能量为主,视觉效果震撼且辨识度高。实战中技能清晰、手感流畅,能提升操作自信与战场表现。整体而言,该皮肤在视觉、特效与实战体验上均表现优异,值得玩家入手。

热心网友
05.06