NAV Profile madness

Time to write article about my last two work days. As each time, when some challenge appears, I learn a lot. This time it applies too. Last days I had a problems with the Profiles in NAV and what they are storing.

1) Translations and Profiles

If you need add new language to the Microsoft Dynamic NAV, it is not just about adding the translated captions to the objects. Even when you translate all in objects, you can still hit non-translated labels on the interface, because the profile stored CaptionML in the delta XML too. And there is first problem – how to "correct" the profile. Of course, you can go and overwrite the things through the Windows Client and the page configuration. But, if there are thousands of the CaptionML to translate? (in my case there were 633 unique strings to translate, many of them on many places and multiple profiles). Example of the part of delta XML:

<Node name="Actions" uri="urn:schemas-microsoft-com:dynamics:NAV:MetaObjects" id="fcfc72f4-831c-4cf9-b0f8-c1782cbe1858">
Node name="Trigger" uri="urn:schemas-microsoft-com:dynamics:NAV:MetaObjects"> 
  <Nodes />
    <Attribute value="OnAction" name="TriggerType" uri="" />
    <Attribute value="a60Action32a62_a45_OnAction" name="Name" uri="" /> 
  <Attribute value="ActionDefinition" name="xsi:type" uri="" />
  <Attribute value="-101" name="ID" uri="" />
  <Attribute value="Action32" name="Name" uri="" />
  <Attribute value="Stornovat žurnál" name="Caption" uri="" />
  <Attribute value="ENU=Reverse Register;CSY=Stornovat žurnál;SKY=Stornovať žurnál" name="CaptionML" uri="" />
  <Attribute value="True" name="Visible" uri="" />
  <Attribute value="fcfc72f4-831c-4cf9-b0f8-c1782cbe1858" name="ControlGUID" uri="" />
  <Attribute value="ReverseRegister" name="Image" uri="" />
  <Attribute value="true" name="Ellipsis" uri="" />
  <Attribute value="Edit" name="RunPageMode" uri="" />
  <Attribute value="Process" name="PromotedCategory" uri="" /> 

What you can do to automate the thing? Waldo will be happy with this: PowerShell

The profile is stored as an XML in the BLOB field in table [Profile Metadata]. You can read it through powershell, find what you want (all attributes with name CaptionML) and replace the value with correct one. BUT: the BLOB field is compressed. How you can read/write the value from PowerShell?

Yes, another challenge. Will be described in separate article… ;-)


I have created two PowerShell scripts. First, Export-NAVProfileCaptionsML.ps1, will read the Profile Metadata and return list of objects having properties "value" and "newvalue". Value is the "original" CaptionML string in form e.g. "ENU=E&ntries;CSY=Po&ložky". You can save this into CSV, make "newvalue" to be e.g. "ENU=E&ntries;CSY=Po&ložky;SKY=Po&ložky".

Example of usage:

Export-NAVProfileCaptionML.ps1 -Server localhost -Database mydb -Filter MYPROFILE | Export-Csv -Path ToTranslate.csv

###translate the ToTranslate.csv in e.g. excel without messing the structure of the header###

Import-Csv -Path ToTranslate.csv | Translate-NAVProfileCaptionML.ps1 -Server localhost -Database mydb -Filter MYPROFILE

After you have translations, you can use second script, Translate-NAVProfileCaptionsML.ps1 and feed it with the array of objects having properties "value" and "newvalue" (you can read it from CSV). It will go through the profiles, search for the CaptionML attributes and if matching "value" is found, it is replaced with "newvalue" and whole XML is stored back to the NAV Blob.


You can find the scripts here: "NAV PowerShell Scripts and TFS Build Templates" on Codeplex


2) Action trigger names and Profiles

After I have solved the translations, I returned back to older issue we had. Users were sometime experiencing errors when clicking on some action on page like:

"Method 'Page116.a60Action32a62_a45_OnAction' not found."

Quick look at the page definition shows us, that the Action32 is not named Action32, but ReverseRegister. Thus the trigger name is different now. Ok, why the NAV client wants to call trigger, with wrong name? Of course, again, the profile. In the XML of the profile, you can find sections like in previous example.

As you can see, there is Attribute saving the action name. Why??? Do not know… may be I even do not want to know…

Ok, what we can do with this? Again, PowerShell script. But, how to find correct trigger name? Hmm… [Object Metadata].[Metadata] for this object looks like this:

<ActionContainers xsi:type="ActionContainerDefinition" ActionContainerType="ActionItems">
  <Actions xsi:type="ActionGroupDefinition" ID="31" CaptionML="CSY=F&amp;unkce;ENU=F&amp;unctions;SKY=F&amp;unkcie" ControlGUID="{00000074-0000-001F-0008-0000836BD2D2}" Image="Action">
    <Actions xsi:type="ActionDefinition" ID="32" Name="ReverseRegister" CaptionML="CSY=Stornovat žurnál;ENU=Reverse Register;SKY=Stornovať žurnál" ControlGUID="{00000074-0000-0020-0008-0000836BD2D2}" Image="ReverseRegister" Ellipsis="1" RunPageMode="Edit" RunObjectSrcTable="0" Promoted="1" PromotedCategory="Process">
      <Trigger TriggerType="OnAction" Name="ReverseRegister_a45_OnAction"/>

Super! We have a trigger name here. But… another problem on the way – how to "connect" these two things together. We have action ID attribute in the Object Metadata, but Action name in the Profile Metadata and no simple ID. But, name is just ID with "Action" on beginning. Lets remove it and take the ID from there… this was simple.


Another PowerShell script, which reads the Profile Metadata, loop all triggers in the XML, than reads the Object Metadata for the page, tries to find the corresponding trigger name and if it does not exists, it fill find it based on the Action ID and correct it. We already have needed functions to read NAV Blob data from PowerShell, thus not hard to create the script. You can find the script under name Fix-NAVProfileTriggerNames.ps1 in the project "NAV PowerShell Scripts and TFS Build Templates" on Codeplex.



Profiles are big pain sometime, because they are storing things which could change and you do not have a simple way to correct it. But thanks to PowerShell, it could be fixed.

P.S.: The script sources are updated on the Codeplex when needed, I recommend to follow the project and keep eye on the updates…  


No Data
  • Hi Kine,

    thank you for the answers. IOW, role tailoring doesn't come with the tools to tailor the roles? Strange concept... Whatever happended to C/AL objects? Shouldn't they be enough to actually set up a NAV system?

    with best regards


No Data