【发布时间】:2020-12-26 21:26:57
【问题描述】:
我正在尝试使用JSON.NET 对SortedDictionary<Time, T> 进行序列化/反序列化,其中Time 是我项目中的自定义类,T 是某种不需要包含在此处的类型。
序列化工作完美。以这本词典为例:
var dictionary = new SortedDictionary<Time, T> {
[Time.Parse("7:00AM")] = ...,
[Time.Parse("8:00AM")] = ...,
[Time.Parse("9:00AM")] = ...
};
(Time.Parse() 是一个从字符串输入构造Time 对象的简单方法。)现在,如果我运行JsonConvert.SerializeObject(dictionary, Formatting.Indented),我会得到这样的结果:
{
"7:00AM": ...,
"8:00AM": ...,
"9:00AM": ...
}
这是因为Time 类覆盖了ToString() 方法,所以字典键可以很容易地转换为字符串。
不幸的是,反序列化在这里失败了。鉴于上一个示例的输出,运行 JsonConvert.DeserializeObject<SortedDictionary<Time, T>>(previousOutput) 会产生异常:
Newtonsoft.Json.JsonSerializationException
无法将字符串“7:00AM”转换为字典键类型“[...].Time”。创建一个 TypeConverter 以从字符串转换为键类型对象。 [...]
好的,这是有道理的。毕竟,如果没有 some 类型的转换器,JSON.NET 就无法知道如何处理这个问题。但是,我的 Time 类已经有一个 Parse(string) 方法。因此,我创建了一个名为 TimeConverter 的 TypeConverter 来使用它,如下所示:
public class TimeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) && base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return value is string s ? Time.Parse(s) : base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
return destinationType == typeof(string) && value is Time t
? t.ToString()
: base.ConvertTo(context, culture, value, destinationType);
}
}
然后我在Time 类声明中添加了一个TypeConverter 属性:
[TypeConverter(typeof(TimeConverter))]
public class Time : IComparable<Time>
{
...
}
但是,这不起作用。仍然抛出完全相同的错误。此外,我尝试在 TimeConverter 方法中放置断点,但它们从未被触发。 JSON.NET 似乎完全忽略了我的转换器。我做错了什么?
【问题讨论】:
标签: c# json json.net typeconverter