在保留序列化上下文和设置的同时引入这些附加属性的最佳方法是什么?
我知道我可以实现JsonConverter并将其添加到序列化器设置中.这是WriteJson的示例实现:
public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer) { var Json = JObject.FromObject(value,serializer); //modify Json by adding some properties ... Json.WriteTo(writer); }
但是,这提出了一些我不确定如何解决的问题:
如果通过设置配置序列化程序:
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
然后尝试调用JObject.FromObject(值,序列化程序)没有任何序列化,因为JSON.NET已经确定该值正在被序列化(因此它忽略了序列化相同引用的进一步尝试).
如果我设置ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize然后我最终得到一个无限递归循环.调用JObject.FromObject(value,serializer)最终重新进入我的自定义JsonConverter的WriteJson.
相反,如果我创建一个新的序列化程序,或调用JObject.FromObject(值)(如this example所示),我将不再使用相同的序列化程序设置.虽然输出将具有额外的属性,但如果已为原始序列化器配置了其他转换器,合同解析器等,则它可能与序列化json的其余部分不匹配.另外,我已经丢失了参考循环处理的序列化上下文,因此将不再跳过原始输出中将跳过的引用.
是否有更好的方法可以挂钩序列化过程,允许您修改原始序列化程序生成的json?
更新:目前我实施了一个不太理想的解决方法,即提供设置工厂Func< JsonSerializerSettings>到我的自定义JsonConverter.提供的设置必须排除转换器以避免递归循环,这不会保留序列化上下文.此外,由于不再配置转换器,因此任何嵌套对象都不会接收其他属性.
解决方法
这种方法不是编写JsonConverter来序列化对象然后添加属性,而是修改特定类型的契约,然后由序列化程序使用.
protected override IList<JsonProperty> CreateProperties(Type type,MemberSerialization memberSerialization) { var Result = base.CreateProperties(type,memberSerialization); //check if this is a type we add properties to if (IsAnnotatedType(type)) { Result.Add(new JsonProperty { PropertyType = typeof(string),PropertyName = "AdditionalProperty",Readable = true,Writable = false,//value provider will receive the object instance when GetValue is called ValueProvider = new AdditionalPropertyValueProvider() }); } return Result; }