Sometimes you just want to see all the properties of a .NET Object, and the NAV debugger doesn’t do this (yet – I wouldn’t be surprised if it’s coming…). Our old friend Reflection is what we need here, but if you do the normal GetProperties off the Type you could be disappointed as this won’t include any inherited properties, and most things in .NET inherit from other classes. The trick is to use the TypeDescriptor object.
This is not major news to .NET people, but it’s not always obvious how to translate these things to C/AL, so below is a quick Codeunit to display all properties from an Object. It uses Table 823 Name/Value Buffer, which doesn’t have a page so you’ll need to create one of those too.
My function to get the Value is the most simple it can be (StringValue), I only put it in a function so I could extend it when I need to as sometimes ToString() doesn’t exactly give you what you want.
OBJECT Codeunit 90000 View DotNET { CODE { VAR tempNameValue : TEMPORARY Record 823; PROCEDURE ViewObjectProperties@1(VAR _object : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Object";Wait : Boolean) : Boolean; VAR typeDescriptor : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.ComponentModel.TypeDescriptor"; propertyCollection : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.ComponentModel.PropertyDescriptorCollection"; property : DotNet "'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.ComponentModel.PropertyDescriptor"; value : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Object"; i : Integer; BEGIN tempNameValue.DELETEALL; propertyCollection := typeDescriptor.GetProperties(_object); FOR i := 0 TO propertyCollection.Count() - 1 DO BEGIN property := propertyCollection.Item(i); value := property.GetValue(_object); AddNameValue(property.Name(),StringValue(value)); END; IF Wait THEN EXIT(PAGE.RUNMODAL(PAGE::"Name/Value View",tempNameValue) = ACTION::LookupOK) ELSE PAGE.RUN(PAGE::"Name/Value View",tempNameValue); END; PROCEDURE StringValue@2(VAR _object : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Object") Text; BEGIN IF ISNULL(_object) THEN EXIT('') ELSE EXIT(_object.ToString()); END; LOCAL PROCEDURE AddNameValue@3(_name : Text;_value : Text); BEGIN WITH tempNameValue DO BEGIN ID += 1; Name := COPYSTR(_name,1,MAXSTRLEN(Name)); Value := COPYSTR(_value,1,MAXSTRLEN(Value)); INSERT; END; END; BEGIN END. } }