【问题标题】:Serializing Timespan in Dictionary<string, object> with Json.NET使用 Json.NET 序列化 Dictionary<string, object> 中的时间跨度
【发布时间】:2012-12-28 07:20:57
【问题描述】:

我有一个实际上是字典的属性。而且我在这本字典中保留了许多类型,例如 TimeSpan、DateTimes 等。但是序列化和反序列化 TimeSpan 是错误的,它会反序列化为字符串。

var dict = new Dictionary<string, object>();
dict.Add("int", 15);
dict.Add("string", "foo");
dict.Add("timeSpan", new TimeSpan(1,1,1));
dict.Add("dateTime", DateTime.Now);

var settings = new JsonSerializerSettings{
    TypeNameHandling = TypeNameHandling.All,
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
};
var serializedObj = JsonConvert.SerializeObject(dict, Newtonsoft.Json.Formatting.Indented, settings);
var deserializedObj = (Dictionary<string, object>)JsonConvert.DeserializeObject(serializedObj, settings);
//Displaying the types with LinqPad:
deserializedObj["int"].GetType().Dump();
deserializedObj["string"].GetType().Dump();
deserializedObj["timeSpan"].GetType().Dump();
deserializedObj["dateTime"].GetType().Dump();

结果:

所以对象中的 TimeSpan 不能反序列化为时间跨度。我也尝试过使用最新版本的 Json.Net。但结果是一样的。

如何指定 TimeSpan 的类型名称?或者我应该编写一个自定义转换器以及如何编写?

编辑:

我做了一些测试,并像这样更改了序列化的 timeSpan 属性:

""timeSpan"": {
    ""$type"": ""System.TimeSpan"",
    ""$value"": ""01:01:01""}

这一次 json.net 可以将其反序列化为 TimeSpan。但是我怎样才能像这样在序列化级别指定 TimeSpan 的 $type 和 $value 呢?

【问题讨论】:

    标签: object serialization json.net deserialization timespan


    【解决方案1】:

    我终于找到了解决办法。我已经为 TimeSpan 编写了一个自定义转换器。但我认为 Json.Net 中有一个错误。因为我不会为像 TimeSpan 这样的原始类型编写转换器。无论如何,这是解决方案:

    public class TimeSpanConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(TimeSpan);
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("$type");
            writer.WriteValue(value.GetType().FullName);
            writer.WritePropertyName("$value");
            writer.WriteValue(value);
            writer.WriteEndObject();
        }
    
        public override object ReadJson(JsonReader reader, Type type, object value, JsonSerializer serializer)
        {
            return value;
        }   
    }
    

    不要忘记将此转换器添加到 json 序列化程序设置中。如果有任何更好的解决方案,我们将不胜感激。

    【讨论】:

      【解决方案2】:

      我也遇到了这个问题,将 System.Guid 作为字典中的值类型。

      我在 Json.NET 问题跟踪器中提交了 this bug

      【讨论】:

        【解决方案3】:

        我挖了一点并找出了根本问题 - Json.NET 的 DefaultContractResolver.CanConvertToString() 返回 true 的任何类型都会发生这种情况。看这里: Significant bug in Json.NET dictionary serialization

        不幸的是,作者目前认为它不是错误。我认为 Json.NET 很棒,但是这个问题吓到我了……

        这是错误页面上的讨论: https://json.codeplex.com/workitem/23833

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-12
          • 2013-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多