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]"
]
}