Nick Prozee
Nick Prozee

Reputation: 2913

Unable to access dynamic property

I have a dynamic object and I am unable to access its properties.

I modified the code below for readability.

I'm using package : Newtonsoft.Json.8.0.1\lib\net45\Newtonsoft.Json.dll

I am trying to read the object mDevice in the code below:

Code

foreach (dynamic mDevice in dynamicList.mobile_devices)
{
    MobileDevice mobileDevice = new MobileDevice() //====> Throws Exception
    {
        Id = mDevice.id,
        Name = mDevice.name
    };
}

The Exception is as following:

'Newtonsoft.Json.Linq.JProperty' does not contain a definition for 'id'

If I use my Watch Window to output the mDevice before the Exception occurs, I get the following result:

Watch Window

Can anyone explain me why I cannot access the properties?

Update
dynamicList Origin:

IGNORE the reason why I am converting XML into JSON this has other irrelevant purposes

string MobileDevicesInJSON = JsonConvert.SerializeXmlNode(doc);
dynamic dynamicList = JsonConvert.DeserializeObject(MobileDevicesInJSON);



Original JSON:

{"?xml":{"@version":"1.0","@encoding":"UTF-8"},"mobile_device_application":{"general":{"id":"5","name":"Acta Dome Calculator - Free","display_name":"Acta Dome Calculator - Free","description":null,"bundle_id":"com.itwcalculator.calculatorforipadfree","version":"3.1.1","internal_app":"true","category":{"id":"-1","name":"No category assigned"},"ipa":{"name":null,"uri":null,"data":null},"icon":null,"mobile_device_provisioning_profile":null,"url":{"@deprecated":"9.4","#text":"https://itunes.apple.com/nl/app/calculator-free/id398129933?mt=8&uo=4"},"itunes_store_url":"https://itunes.apple.com/nl/app/calculator-free/id398129933?mt=8&uo=4","deployment_type":"Install Automatically/Prompt Users to Install","deploy_automatically":"true","deploy_as_managed_app":"true","remove_app_when_mdm_profile_is_removed":"false","prevent_backup_of_app_data":"false","keep_description_and_icon_up_to_date":"false","free":"true","take_over_management":"false","host_externally":"true","external_url":"https://itunes.apple.com/nl/app/calculator-free/id398129933?mt=8&uo=4","site":{"id":"1","name":"Acta Dome"}},"scope":{"all_mobile_devices":"false","all_jss_users":"false","mobile_devices":{"mobile_device":{"id":"9","name":"iPad R&D 01S","udid":"dd1dff5d598e3fce0b4b16288f0b9bf1551d0eb2","wifi_mac_address":"9C:35:EB:53:00:84"}},"mobile_device_groups":{"mobile_device_group":{"id":"9","name":"Acta Dome Unassigned"}},"buildings":null,"departments":null,"jss_users":{"user":[{"id":"9","name":"ACTA_Astrid"},{"id":"7","name":"ACTA_RenD01"}]},"jss_user_groups":{"user_group":{"id":"7","name":"Acta Dome StudentGroup 01"}},"limit_to_users":{"user_groups":null},"network_limitations":{"any_ip_address":"true","network_segments":null},"limitations":{"users":null,"user_groups":null,"network_segments":null},"exclusions":{"mobile_devices":null,"mobile_device_groups":null,"buildings":null,"departments":null,"jss_users":null,"jss_user_groups":null,"users":null,"user_groups":null,"network_segments":null}},"self_service":{"self_service_description":null,"self_service_icon":null,"feature_on_main_page":"false","self_service_categories":null}}}

Upvotes: 4

Views: 3937

Answers (4)

Kos
Kos

Reputation: 567

This could be a solution.

foreach (dynamic mDevice in dynamicList)
{
    object mDeviceProperties = mDevice.Value;

    var mobileDevice = JsonConvert.DeserializeObject<MobileDevice>(mDeviceProperties.ToString());
}

Upvotes: 0

Ivan Stoev
Ivan Stoev

Reputation: 205589

If you look at the Type column in the Watch window (that you haven't fully shown in your post, and it contains a quite important information), you will see that the type of the mDevice is Newtonsoft.Json.Linq.JProperty (which btw is also implied from the exception message) and not a Newtonsoft.Json.Linq.JObject as you expect. Which in turn means the dynamicList.mobile_devices is not a Newtonsoft.Json.Linq.JArray as you expect, and indeed it is a Newtonsoft.Json.Linq.JObject instance. So the whole logic is wrong. Here is a working example based on the "Original JSON" from the post:

string originalJSON = ...;
dynamic root = JsonConvert.DeserializeObject(originalJSON);
dynamic mobileDevices = root.mobile_device_application.scope.mobile_devices;
dynamic mobileDevice = mobileDevices.mobile_device;
var id = (int)mobileDevice.id;
var name = (string)mobileDevice.name;

or alternatively

foreach (var item in mobileDevices)
{
    dynamic mobileDevice = item.Value;
    var id = (int)mobileDevice.id;
    var name = (string)mobileDevice.name;
}

As a general advice, start using the Locals/Watch window capabilities other than values. For instance, there is something called "Dynamic View" which appears at the bottom of the expanded object with dynamic support, which in this case shows :

enter image description here

Upvotes: 3

Hogan
Hogan

Reputation: 70523

Look at the object, change to this code it should work:

    Id = mDevice.mobile_device.id,
    Name = mDevice.mobile_device.name

this is clear from your watch window.


I don't see anything called mobile_devices -- do you mean mobile_device?

The code you show should not iterate the loop because that property name shouldn't exist.

Upvotes: 1

Kapil
Kapil

Reputation: 9959

The dynamic object here is a dictionary(key value pair) where "mobile_device" is a key and corresponding object containing id,name etc is value of this key.

you should be able to access that using mobile_device as key on mDevice like mDevice["mobile_device"]. This should return you an object which again has key value pairs (id key and 9 is value , name key and ipad is value ....). again use the same syntax (key/value) on the object returned to get the corresponding value.

Upvotes: 2

Related Questions