如何在序列化中向JSON添加类型信息?(How to add types information to JSON on serialization?)

编程入门 行业动态 更新时间:2024-10-08 03:41:09
如何在序列化中向JSON添加类型信息?(How to add types information to JSON on serialization?)

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就像在此问题中描述的那样。

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

Angular requires Date objects in many places whereas JSON contains string representation of the date.

I want to add an array of properties which contain date values:

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 should then be serialized like this:

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

This allows me to automatically convert strings to date objects at the client side without testing every property whether it is convertible to Date like it is described in this question.

I can collect the paths of date properties, but have no idea how to add populated array to the root.

最满意答案

您可以转换为中间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]" ] }

You could convert to an intermediate JObject and add the property there. For instance, given the following converter:

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; } } }

You can do:

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);

And the result is:

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

更多推荐

本文发布于:2023-07-09 10:31:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1085642.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:中向   类型   序列化   如何在   信息

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!