动态的JSON对象具有数字键

3

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

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

所以我无法编写

dynObj.address.100  

据我所知,无法使用索引器以此方式获取该对象。

dynObj.address["100"]  

请告诉我如何使这个工作起来。

你尝试在Visual Studio中设置断点并检查动态对象了吗? - Yet Another Geek
@Cybernate 我认为这不是重复的,因为 @Tror 正在问如何使用 C# 的 dynamic 关键字访问一个属性,其中该属性的名称在 C# 中不被视为有效标识符。您引用的问题特定于Javascript。 - Donut
Cybernate,这不是重复的问题。他的问题是关于JavaScript的,而我的问题是关于C#的。 - Tror
又一个极客,这里是断点窗口 - Tror
3个回答

2
从源代码中我所看到的,他通过私有字典来解析属性,因此您需要使用反射来访问字典键,或者稍微修改他的代码,以便在DynamicJSONObject中的TryGetMember方法如下所示(并使用__numeric__来获取键,例如data.address.__numeric__100,然后避免将__numeric__用作键)。
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;
        }

谢谢,我会尝试的。至少比没有好。我想避免这种垃圾,但这是第三方服务,我无能为力。 - Tror
这只是一个临时解决方案,原始代码中并没有考虑到这个问题。更好的解决方案应该是类似于Linq-to-XML类型的访问,但这需要进行大量修改。 - Yet Another Geek

1

我的开源框架ImpromptuInterface具有通过字符串名称调用任何C# 4动态对象的方法的功能

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

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


0
标识符必须以字母、下划线(_)或美元符号($)开头;后续字符也可以是数字(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>

顺便说一下,键可以是数字(如答案中所示),只有标识符不能是数字。因此,您必须像您尝试的那样进行访问。对于数字键,您只需要省略引号!并且您的JSON字符串不会成为一个对象而不进行评估,因此在这个例子中它严格来说是一个JavaScript对象而不是JSON,但这对主题没有影响。


Joe,我知道这点,这就是为什么我写下了“我不会写”的原因。 - Tror
Joe,你看到我的问题了吗? - Tror
是的,我已经编辑了答案。还有什么不对吗? - The Surrican
Joe,非常感谢你的努力,但我问的是C#,不是JavaScript :) - Tror
哦,抱歉,我看漏了你问题的重点。至少现在我知道为什么作为Java程序员需要类了。“我不看C#!” - The Surrican

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接