嵌套在其他类中的自定义类如何按预定义规则完成Json序列化?
解决方案
你之前重写Event的ToString()方法仅在手动调用时生效,Newtonsoft.Json(Json.NET)序列化嵌套对象时默认通过反射读取类的公共属性完成序列化,不会自动调用类的ToString()方法,因此你在ToString()中指定的时间格式规则不会在嵌套序列化时触发。
下面给出两种满足「内部类序列化逻辑自治、外层类无需感知」要求的实现方案:
方案1:给时间字段指定序列化格式(最简便,适合仅字段格式自定义场景)
直接在Event类的Timestamp属性上添加JsonProperty特性指定日期格式,该规则对所有序列化场景生效:
public class Event { public string Type { get; set; } [JsonProperty(DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffffffZ")] public DateTime Timestamp { get; set; } public override string ToString() { // 此处无需再单独传入Converter,属性特性已全局生效 return JsonConvert.SerializeObject(this); } }
修改后无需改动UserEvent的任何代码,嵌套序列化时Timestamp会自动按指定格式输出。
方案2:为Event类自定义JsonConverter(灵活度高,适合复杂序列化规则场景)
如果Event的序列化逻辑不止时间格式调整,还有其他自定义规则,可以为Event绑定专属的序列化转换器,所有场景下序列化Event实例时都会自动调用该转换器:
第一步:实现自定义Converter
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Globalization; public class EventConverter : JsonConverter<Event> { public override void WriteJson(JsonWriter writer, Event value, JsonSerializer serializer) { writer.WriteStartObject(); writer.WritePropertyName(nameof(Event.Type)); writer.WriteValue(value.Type); writer.WritePropertyName(nameof(Event.Timestamp)); writer.WriteValue(value.Timestamp.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ")); writer.WriteEndObject(); } public override Event ReadJson(JsonReader reader, Type objectType, Event existingValue, bool hasExistingValue, JsonSerializer serializer) { // 反序列化逻辑按需实现,不需要反序列化可直接抛出NotImplementedException JObject jObj = JObject.Load(reader); return new Event { Type = jObj[nameof(Event.Type)].Value<string>(), Timestamp = DateTime.ParseExact( jObj[nameof(Event.Timestamp)].Value<string>(), "yyyy-MM-ddTHH:mm:ss.fffffffZ", CultureInfo.InvariantCulture ) }; } }
第二步:给Event类绑定Converter
[JsonConverter(typeof(EventConverter))] public class Event { public string Type { get; set; } public DateTime Timestamp { get; set; } public override string ToString() { return JsonConvert.SerializeObject(this); } }
该方案同样不需要修改任何外层包装类的代码,Event的序列化逻辑完全由自身内部控制。
内容的提问来源于stack exchange,提问作者Alcibiades
相关产品推荐
相关产品推荐

