为什么不使用IsoDateTimeConverter来序列化Dictionary <datetime,int =“”>

时间:2016-09-08 07:54:16

标签: c# serialization asp.net-web-api json.net

返回字典的webAPI方法的结果未使用IsoDateTimeConverter中定义的格式序列化

这是我的配置:

public static class WebApiConfig
{
    //Web API configuration and services
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
        config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter
        {
            DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'"
        });
    }
}

这是webAPI方法的一个示例

[Route("GetPlanning")]
[HttpPost]
public Dictionary<DateTime, IEnumerable<int>> GetPlanning()
{
    Dictionary<DateTime, IEnumerable<int>> planning = new Dictionary<DateTime,IEnumerable<int>>();
    planning.Add(DateTime.UtcNow, new List<int>(){0,1,2});
    return planning;
}

在客户端,结果是一个对象,其属性是一个没有毫秒的日期。

如果我返回一个数组:return planning.ToArray();,结果是一个对象键值数组,其日期为毫秒。

那么为什么格式是在数组中的日期而不是在字典中?

1 个答案:

答案 0 :(得分:2)

IsoDateTimeConverter未用于字典键的原因是Json.NET没有序列化键 - 它只是将它们转换为字符串。来自docs

  

序列化字典时,字典的键将转换为字符串并用作JSON对象属性名称。为密钥编写的字符串可以通过覆盖密钥类型的ToString()或通过实现TypeConverter来自定义。在反序列化字典时,TypeConverter还将支持再次转换自定义字符串。

因此,在将字典键转换为JSON时,不会使用转换器,包括IsoDateTimeConverter

话虽如此,不再需要IsoDateTimeConverter。来自Serializing Dates in JSON

  

从Json.NET 4.5开始,默认情况下使用ISO 8601格式编写日期,并且不需要使用此转换器。

通过设置JsonSerializerSettings.DateFormatString

,可以获得相同的日期格式
config.Formatters.JsonFormatter.SerializerSettings.DateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'";

但是这会如何影响字典键转换为JSON?事实证明,将DateTime转换为string作为字典键时,Json.NET 会尊重此设置,如reference source所示。因此:

var time = DateTime.Now;

Dictionary<DateTime, IEnumerable<int>> planning = new Dictionary<DateTime, IEnumerable<int>>();
planning.Add(DateTime.UtcNow, new List<int>() { 0, 1, 2 });
var root = new { today = time, planning = planning };

var settings = new JsonSerializerSettings
{
    DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc,
    DateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'",
};
var json = JsonConvert.SerializeObject(root, Formatting.Indented, settings);
Console.WriteLine(json);

为用作字典键并用作属性的DateTime值生成一致格式的所需输出:

{
  "today": "2016-09-09T03:54:51.704Z",
  "planning": {
    "2016-09-09T03:54:51.704Z": [
      0,
      1,
      2
    ]
  }
}