Newtonsoft JSON序列化同一输入生成不同输出问题咨询
问题分析与解决思路
这问题我之前帮同事排查过,大概率是两个项目里Newtonsoft.Json的版本或者隐式配置差异导致的,咱们拆成两个点来聊:
1. 首字母大小写差异(token vs Token)
这种情况常见的原因有两个:
- Newtonsoft.Json版本差异:不同版本对
[DataContract]/[DataMember]属性的处理逻辑有变化。比如旧版本可能默认忽略DataMember的Name属性,直接用类属性的驼峰命名(小写首字母),而新版本会严格遵循DataMember里指定的Name值(也就是Token大写首字母)。 - Web服务引用生成的类有差异:其中一个项目在添加Web Service引用时,可能勾选了“重用类型”或者修改了生成选项,导致类的
[DataMember]属性被改动——比如Name值没正确生成,或者干脆没带这个属性,让Newtonsoft自己推断命名规则。
2. JSON中新增\r\n
这个其实是序列化时的格式化设置不同:
- 如果你看到JSON里有
\r\n,说明这个项目的序列化用了Formatting.Indented(带缩进和换行的格式化输出),而另一个项目用的是默认的Formatting.None(紧凑无换行的输出)。 - 你说没手动配置Newtonsoft,但很多框架(比如ASP.NET Web API、WCF)会全局设置Json序列化的格式,或者某个依赖库悄悄修改了
JsonConvert.DefaultSettings,导致默认行为不一样。
验证与解决办法
- 先查版本:打开两个项目的NuGet包管理器,看Newtonsoft.Json的版本是否完全一致,不一致的话统一成同一个版本试试。
- 检查全局配置:在项目里搜索
JsonConvert.DefaultSettings,或者查看Web.config/App.config里有没有关于Newtonsoft.Json的配置节点,比如有没有设置Formatting或者ContractResolver。 - 对比生成的类:找到两个项目里Web Service生成的类文件,对比
[DataMember]属性的内容,看是否有差异。 - 显式指定序列化设置:最稳妥的办法是不管项目默认配置,序列化时手动指定设置,确保两个项目行为一致:
var settings = new JsonSerializerSettings { // 如果你要保留Token的大写首字母,用DefaultContractResolver;要小写用CamelCasePropertyNamesContractResolver ContractResolver = new DefaultContractResolver(), // 要紧凑输出就用Formatting.None,要格式化就用Formatting.Indented Formatting = Formatting.None }; var jsonString = JsonConvert.SerializeObject(yourWebServiceObject, settings);
内容的提问来源于stack exchange,提问作者shinjidev
相关产品推荐
相关产品推荐

