加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

具有额外属性的Json.NET序列化;保留序列化程序设置

发布时间:2020-12-16 18:41:00 所属栏目:百科 来源:网络整理
导读:当 JSON.NET序列化类型时,我想在json输出中为特定类型的实例引入一些元数据属性. 在保留序列化上下文和设置的同时引入这些附加属性的最佳方法是什么? 我知道我可以实现JsonConverter并将其添加到序列化器设置中.这是WriteJson的示例实现: public override
当 JSON.NET序列化类型时,我想在json输出中为特定类型的实例引入一些元数据属性.

在保留序列化上下文和设置的同时引入这些附加属性的最佳方法是什么?

我知道我可以实现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.提供的设置必须排除转换器以避免递归循环,这不会保留序列化上下文.此外,由于不再配置转换器,因此任何嵌套对象都不会接收其他属性.

解决方法

我发现我可以实现自定义IContractResolver并覆盖CreateProperties以包含任意数量的其他属性以及提供实际属性值的IValueProvider.

这种方法不是编写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;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读