【发布时间】:2013-12-12 00:09:06
【问题描述】:
我反映了 JSON.NET JavaScriptDateTimeConverter 类代码,复制了它,并将类重命名为 AS3DateTimeConverter,以便我可以修改它以更精确和强类型的庄园格式化 DateTime 对象。
我让它根据 JSON.NET 输出强类型对象的方式输出一个类型,如下所示:
{"$type":"System.DateTime, mscorlib","ticks":0}
JsonConverter 的重写 WriteJson 方法运行以生成该值。
但是,当我尝试使用完全相同的设置和相同的转换器反序列化字符串时,被覆盖的 ReadJson 方法永远不会有机会运行并从 ticks 属性构造 DateTime,因为会发生以下错误:
无法反序列化当前 JSON 对象(例如 {"name":"value"}) 进入类型“System.DateTime”,因为该类型需要 JSON 原语 正确反序列化的值(例如字符串、数字、布尔值、null)。
要修复此错误,请将 JSON 更改为 JSON 原始值 (例如字符串、数字、布尔值、空值)或更改反序列化类型 所以它是一个普通的 .NET 类型(例如,不是像 整数,而不是数组或列表之类的集合类型) 从 JSON 对象反序列化。也可以添加 JsonObjectAttribute 强制它从 JSON 对象反序列化。
路径“记号”,第 1 行,位置 45。
这是否是某种错误或限制,因为它是值类型,所以不允许我恢复 DateTime 类型?还是我错过了什么?
这里是序列化设置:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
settings.ConstructorHandling = ConstructorHandling.Default;
settings.TypeNameHandling = TypeNameHandling.All;
settings.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
settings.DateParseHandling = DateParseHandling.DateTime;
settings.Converters.Add( new AS3DateTimeConverter() );
//settings.Binder = new AS3SerializationBinder();
string s = JsonConvert.SerializeObject( new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ), settings );
object o = JsonConvert.DeserializeObject( s, settings ); //s = "{\"$type\":\"System.DateTime, mscorlib\",\"ticks\":0}" //ERROR OCCURS HERE
【问题讨论】:
-
这实际上不会存储滴答声,它将存储自 1970 年 1 月 1 日以来经过的毫秒数,可能还会存储滴答声以获得更好的往返精度,但关键是 JsonConverter 的重写 ReadJson 方法永远不会甚至有机会运行,大概是因为 DateTime 是值类型而不是类?
-
你能显示你的转换器代码吗?
-
我可以,但这不值得。它只是扩展了内置的 JsonConverter 并覆盖了 WriteJson 和 ReadJson 方法。 WriteJson 方法运行良好并生成我显示的 JSON 字符串。问题是,尽管字符串包括
"$type":"System.DateTime",但转换器的 CanConvert 方法永远不会使用该类型调用,并且转换器的 ReadJson 方法永远不会被调用。就好像它甚至没有尝试使用我的转换器,甚至没有测试它是否可以使用。也许这是一个绑定问题,但我认为这是自动的。 -
我还尝试修改 WriteJson 方法以将对象写入称为“DateTimeWrapper”的自定义引用类型类,该类仅存储单个整数“ticks”,因此字符串
{"$type":"mynamespace.DateTimeWrapper","ticks":0}由序列化,但奇怪的是,在尝试反序列化字符串时,我的 JsonConverter 的 CanConvert 方法被调用,但它接收整数类型而不是 mynamespace.DateTimeWrapper 类型。我觉得这很奇怪。就像认为它在反序列化过程中忽略了嵌入在 JSON 对象字符串中的“$type”。 -
我只是能够重现该问题。你是对的,如果你只是想反序列化一个裸露的
DateTime,转换器不会被调用。但是,如果您将 DateTime 包装在另一个对象中,它就可以工作。
标签: json serialization json.net converter strong-typing