【问题标题】:Dynamic json object with numerical keys带有数字键的动态 json 对象
【发布时间】:2011-09-17 06:34:45
【问题描述】:

我有一个 json 对象,我在 this 答案的帮助下将其转换为动态 C# 对象。它工作得很好,但问题是这个对象有数字键。例如,

var jsStr = "{address:{"100": {...}}}";  

所以我写不出来

dynObj.address.100  

而且,据我所知,我不能使用索引器来获取这样的对象

dynObj.address["100"]  

请向我解释我如何才能让它工作。

【问题讨论】:

  • 你试过在visual studio中设置断点,检查动态对象吗?
  • @Cyber​​nate 我不认为这是重复的,因为@Tror 正在询问如何使用 C# 的 dynamic 关键字来访问属性名称不被视为有效标识符的属性在 C# 中。您引用的问题特定于 Javascript。
  • Cyber​​nate,这不是重复的。他的问题是关于 javascript,但我的问题是关于 C#
  • 又一个极客,这里是breakpoint window

标签: c# json dynamic key numerical


【解决方案1】:

据我从源代码中可以看出,他通过私有字典解析属性,因此您必须使用反射来访问字典键,或者稍微修改他的代码,以便 DynamicJSONObject 中的 TryGetMember 如下(和使用 __numeric__ 获取 key 例如 data.address.__numeric__100,然后避免使用 __numeric__ 作为 key):

public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var name = binder.Name; 
            //Code to check if key is of form __numeric__<number> so that numeric keys can be accessed
            if (binder != null && binder.Name != null && binder.Name.StartsWith("__numeric__"))
            {
                name = binder.Name.Substring(11);
            }

            if (!_dictionary.TryGetValue(name, out result))
            {
                // return null to avoid exception.  caller can check for null this way...
                result = null;
                return true;
            }

            var dictionary = result as IDictionary<string, object>;
            if (dictionary != null)
            {
                result = new DynamicJsonObject(dictionary);
                return true;
            }

            var arrayList = result as ArrayList;
            if (arrayList != null && arrayList.Count > 0)
            {
                if (arrayList[0] is IDictionary<string, object>)
                    result = new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x)));
                else
                    result = new List<object>(arrayList.Cast<object>());
            }

            return true;
        }

【讨论】:

  • 谢谢,我试试。至少总比没有好。我想避免这种废话,但这是第三方服务,我无能为力。
  • 这只是针对原始代码中未解决的问题的一个不完整的解决方案。更好的解决方案应该是类似于 Linq-to-XML 类型的访问,但这需要进行大量修改。
【解决方案2】:

我的开源框架 ImpromptuInterface 具有任何 C# 4 动态对象的 call dynamic members via string name 方法。

object tOut =Impromptu.InvokeGet(dynObj.address,"100");

我用ExpandoObject 对其进行了测试,它似乎工作得很好。

【讨论】:

    【解决方案3】:

    标识符必须以 字母、下划线 (_) 或美元符号 ($);后面的字符也可以 数字 (0-9)。因为 JavaScript 是 区分大小写,字母包括 字符“A”到“Z”(大写) 和字符“a”到“z” (小写)。从 JavaScript 开始 1.5、ISO 8859-1 或 Unicode 字母(或 \uXXXX Unicode 转义序列)可以 在标识符中使用。

    引用自:http://en.wikipedia.org/wiki/JavaScript_syntax#Variables

    抱歉,我理解错了问题,这里有一个工作示例,您可以根据需要进行调整:

    <script>
    var jsStr = {address:{'100': 'test'}};
    var test = jsStr.address;
    console.log(test);
    alert(test[100]);        
    </script>
    

    btw 键可以是数字(如您在答案中的示例中所见),只有标识符不能。所以你必须像你尝试的那样访问。你只需要离开数字键的引号!并且你的 json 字符串不会是一个没有评估的对象,所以在这个例子中,严格来说它是一个 javascript 对象而不是 json,但它与主题无关

    【讨论】:

    • 乔,我知道,所以我写了“我不会写”
    • 乔,你看我的问题了吗?
    • 是的,我做了并编辑了答案?这还有什么问题吗?
    • 乔,非常感谢您的努力,但我问的是 c#,而不是 javascript :)
    • 哦,抱歉,毕竟我过度阅读了您问题的重要部分。至少知道我真的知道为什么我作为一个 java 程序员需要类。 “我没看到锋利!” (c#)
    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 2019-08-23
    • 2018-05-07
    相关资源
    最近更新 更多