Json.NET反序列化与引用动态对象 [英] Json.NET Deserialization into dynamic object with referencing

查看:290
本文介绍了Json.NET反序列化与引用动态对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能得到Json.NET反序列化到动态对象,但仍然做参考的分辨率结果
动态D = JsonConvert.DeserializeObject< ExpandoObject>(...)正如结果
动态D = JsonConvert.DeserializeObject(...)返回一个动态对象,但他们不解决 $ REF 的$ id 部分。 (安 ExpandoObject EO 为例只会有 EO [$ REF] =...并没有按'吨有它应有的性能,因为它是不一样的的$ id -object)

How can I get Json.NET to deserialize into dynamic objects but still do reference resolution?
dynamic d=JsonConvert.DeserializeObject<ExpandoObject>(...) just as
dynamic d=JsonConvert.DeserializeObject(...) returns a dynamic object but they don't resolve the $ref and $id parts. (An ExpandoObject eo for example will only have eo["$ref"]="..." and doesn't have the properties it should have because it's not the same as the $id-Object)

我已经找到了,是我所需要的合同解析器解析到一个动态的合同 - 这 ExpandoObject 不仅如果我明确告诉Json.NET使用自定义 ContractResolver

What I've found out is that I need the contract resolver resolve to a dynamic contract - which ExpandoObject only does if I explicitly tell Json.NET with a custom ContractResolver.

不过它似乎 ExpandoObject 解析与它自己的转换器,它再次失败。

Still It seems the ExpandoObject is parsed with it's own Converter and it fails again.

我试过一个自定义类继承 IDynamicMetaObjectProvider 这就造成了一个无限循环和没 ŧ看起来正确的事情。我真的期待一些简单的解决方案要获得 ExpandoObject 有参考的分辨率。

I've tried a custom class inheriting from IDynamicMetaObjectProvider which resulted in an infinite loop and didn't seem like the right thing. I would actually expect some easy solution to get ExpandoObject to have reference resolution.

任何帮助吗?

推荐答案

我做到了,现在是一个后处理步骤,并且在做自己的参考储蓄和重新布线递归函数的方式:

The way I did it now is with a postprocessing step and a recursive function that's doing its own reference saving and rewiring:

    private static void Reffing(this IDictionary<string, object> current, Action<object> exchange,IDictionary<string, object> refdic)
    {
        object value;
        if(current.TryGetValue("$ref", out value))
        {
            if(!refdic.TryGetValue((string) value, out value))
                throw new Exception("ref not found ");
            if (exchange != null)
                exchange(value);
            return;
        }
        if (current.TryGetValue("$id", out value))
        {
            refdic[(string) value] = current;
        }
        foreach (var kvp in current.ToList())
        {
            if (kvp.Key.StartsWith("$"))
                continue;
            var expandoObject = kvp.Value as ExpandoObject;
            if(expandoObject != null)
                Reffing(expandoObject,o => current[kvp.Key]=o,refdic);
            var list = kvp.Value as IList<object>;
            if (list == null) continue;
            for (var i = 0; i < list.Count; i++)
            {
                var lEO = list[i] as ExpandoObject;
                if(lEO!=null)
                    Reffing(lEO,o => list[i]=o,refdic);
            }
        }
    }



作为:

used as:

        var test = JsonConvert.DeserializeObject<ExpandoObject>(...);
        var dictionary = new Dictionary<string, object>();
        Reffing(test,null,dictionary);

这篇关于Json.NET反序列化与引用动态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆