3

I have a json object which I converted to dynamic C# object with help of this answer. It works just fine, but trouble is that this object has numerical keys. For instance,

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

So I can't wirte

dynObj.address.100  

And, as I know, I can't use indexers to get this object like this

dynObj.address["100"]  

Please explain to me how I can get this working.

4
  • Have you tried setting a breakpoint in visual studio, and inspect the dynamic object? Commented Jun 17, 2011 at 14:54
  • @Cybernate I don't think this is a duplicate, as @Tror is asking how C#'s dynamic keyword can be used to access a property where the name of the property is not considered a valid identifier in C#. The question you referenced is specific to Javascript. Commented Jun 17, 2011 at 14:56
  • Cybernate, this is not a duplicate. His question is about javascript, but mine is about C# Commented Jun 17, 2011 at 14:58
  • Yet Another Geek, here is the breakpoint window Commented Jun 17, 2011 at 15:02

3 Answers 3

2

As far as I can see from the source code he resolves the properties through a private dictionary, so you have to use reflection to access the dictionary key, or modify his code a bit so that TryGetMember in DynamicJSONObject is the following (and use __numeric__ to get the key e.g. data.address.__numeric__100, and then avoid using __numeric__ as a 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;
        }
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I'll try it. At least it's better than nothing. I'd like to avoid such crap, but this is third-party service and I can do nothing with it.
It was just a patchy solution to a problem that was not though off in the original code. A better solution would have been something like Linq-to-XML type of access, but that required a lot of modification.
1

My opensource framework ImpromptuInterface has methods to call dynamic members via string name of any C# 4 dynamic object.

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

I tested it with an ExpandoObject it seemed to work just fine.

Comments

0

An identifier must start with a letter, underscore (_), or dollar sign ($); subsequent characters can also be digits (0-9). Because JavaScript is case sensitive, letters include the characters "A" through "Z" (uppercase) and the characters "a" through "z" (lowercase). Starting with JavaScript 1.5, ISO 8859-1 or Unicode letters (or \uXXXX Unicode escape sequences) can be used in identifiers.

Quoted from: http://en.wikipedia.org/wiki/JavaScript_syntax#Variables

Oh I am sorry mis understood the question, well here you go with a working example you can adjust to your needs:

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

btw key CAN be numeric (as you see in the example in the answer), only the identifiers cannot. so you have to access just like you tried. you only have to leave away the quotes for numeric keys! and your json string will not be an object without evaluation, so in this example its strictly speaking a javascript object and not json but it doesnt matter to t he subject

5 Comments

Joe, I know this, thats why I wrote that "I can't write"
Joe, Did you READ my question?
yes i did and edited the anwer? anything still wrong with that?
Joe, thanks a lot for your effort, but I asked about c#, not javascript :)
oh sorry guess i overread essential parts of your question after all. at least know i really know why i, as a java programmer, need classes. "i don't see sharp!" (c#)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.