使用NewtonSoft JsonConvert.SerializeObject序列化DateTime后出现转义双引号导致反序列化失败的原因及规避方法咨询
首先咱们来拆解你遇到的问题:正常情况下,JsonConvert.SerializeObject序列化DateTime类型的值时,应该直接输出类似"2021-02-19T10:00:00"的结果——注意这里的双引号是JSON字符串的标准包裹,本身不应该带转义符。你看到的转义双引号(比如\"2021-02-19T10:00:00\"),大概率是因为出现了二次序列化的情况,或者序列化配置被修改了。
可能的原因
二次序列化操作:这是最常见的场景。比如你先单独序列化了
DateTime对象得到字符串,然后把这个字符串作为另一个对象的属性值,再次执行序列化。举个例子:DateTime myDate = new DateTime(2021, 2, 19, 10, 0, 0); // 第一次序列化,得到 "2021-02-19T10:00:00" string dateStr = JsonConvert.SerializeObject(myDate); // 把字符串放进对象,再次序列化,就会把原字符串的双引号转义 var wrapper = new { Date = dateStr }; string finalJson = JsonConvert.SerializeObject(wrapper); // finalJson会是 {"Date":"\"2021-02-19T10:00:00\""}这种情况下,第二次序列化会把已经是字符串的
dateStr当作普通字符串处理,自然会转义其中的双引号。错误的序列化配置:如果你的代码中设置了
StringEscapeHandling.EscapeHtml或者StringEscapeHandling.EscapeNonAscii,可能会导致额外的转义。不过默认配置下不会出现这种问题,除非你主动修改了设置。属性类型误设:虽然你说属性是
DateTime类型,但可以再确认一下——如果属性实际是string类型,而你手动把DateTime转成字符串后赋值,序列化时也会出现带转义的双引号(因为本质是序列化字符串)。
如何避免替换操作,解决问题
针对不同原因,对应解决方法:
避免二次序列化:直接序列化包含
DateTime属性的完整对象,而不是先单独序列化DateTime。比如上面的例子应该改成:DateTime myDate = new DateTime(2021, 2, 19, 10, 0, 0); var wrapper = new { Date = myDate }; string finalJson = JsonConvert.SerializeObject(wrapper); // 此时finalJson是 {"Date":"2021-02-19T10:00:00"},没有额外转义检查并重置序列化配置:如果你的代码中使用了自定义的
JsonSerializerSettings,确保没有设置多余的转义规则。比如:var settings = new JsonSerializerSettings { // 不要设置StringEscapeHandling为EscapeHtml/EscapeNonAscii,除非有明确需求 StringEscapeHandling = StringEscapeHandling.Default }; string json = JsonConvert.SerializeObject(yourObject, settings);确认属性类型:检查你的实体类,确保对应的属性确实是
DateTime(或DateTime?)类型,而不是string。比如:public class MyClass { // 正确的类型 public DateTime MyDate { get; set; } // 错误的类型(如果用这个,序列化时会转义字符串的引号) // public string MyDate { get; set; } }
按照上面的方法调整后,序列化出来的DateTime值应该是标准的JSON字符串格式,不需要手动替换转义双引号,反序列化也能正常执行。
内容的提问来源于stack exchange,提问作者Roel Alblas

