如何在序列化时向JSON添加类型信息



Angular在很多地方都需要Date对象,而JSON包含日期的字符串表示。

我想添加一个包含日期值的属性数组:

class Foo
{
    public int IntProp {get;set;}
    public DateTime? Prop1 {get;set;}
    public DateTime  Prop2 {get;set;}
    public Bar Bar {set;set;}
}
class Bar
{
    public DateTime Prop {get;set;}
    public IEnumerable<DateTime?> Dates {get;set;} 
}

Foo应该像这样序列化:

{
   "IntProp": 1,
   "Prop1": "...",
   "Prop2": "...",
   "Bar": {
       "Prop": "..."
   },
   "<Dates>": [ "Prop1", "Prop2", "Bar.Prop", "Bar.Dates"]
}

这允许我在客户端自动将字符串转换为日期对象,而不需要测试每个属性是否可以像这个问题中描述的那样转换为Date

我可以收集日期属性的路径,但不知道如何将填充的数组添加到根。

您可以转换为中间的JObject并在那里添加属性。例如,给定以下转换器:

public class PathLoggingDateTimeConverter : IsoDateTimeConverter
{
    public const string DatePathPropertyName = "<Dates>";
    readonly List<string> paths = new List<string>();
    public override bool CanConvert(Type objectType)
    {
        if (!base.CanConvert(objectType))
            return false;
        // Not for DateTimeOffset
        return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        base.WriteJson(writer, value, serializer);
        if (value != null)
            paths.Add(writer.Path);
    }
    public IList<string> Paths { get { return paths; } }
}

你可以这样做:

        var root = new Foo
        {
            IntProp = 101,
            Prop1 = DateTime.Today.ToUniversalTime(),
            Prop2 = DateTime.Today.ToUniversalTime(),
            Bar = new Bar
            {
                Prop = DateTime.Today.ToUniversalTime(),
                Dates = new List<DateTime?> { null, DateTime.Today.ToUniversalTime() },
            },
        };
        var converter = new PathLoggingDateTimeConverter();
        var settings = new JsonSerializerSettings { Converters = new[] { converter } };
        var obj = JObject.FromObject(root, JsonSerializer.CreateDefault(settings));
        obj[PathLoggingDateTimeConverter.DatePathPropertyName] = JToken.FromObject(converter.Paths);
        Console.WriteLine(obj);

结果是:

{
  "IntProp": 101,
  "Prop1": "2016-10-25T04:00:00Z",
  "Prop2": "2016-10-25T04:00:00Z",
  "Bar": {
    "Prop": "2016-10-25T04:00:00Z",
    "Dates": [
      null,
      "2016-10-25T04:00:00Z"
    ]
  },
  "<Dates>": [
    "Prop1",
    "Prop2",
    "Bar.Prop",
    "Bar.Dates[1]"
  ]
}

相关内容

  • 没有找到相关文章

最新更新