Metadata Server

Metadata Server Logo

Speed up your HTML web resources by caching metadata such as localised field labels and options set values!

If you’ve developed an HTML web resource for Dynamics CRM that includes field labels, option sets or any other element that is stored in the Dynamics CRM metadata then you’ll know about the delay each time the your UI is rendered whilst information is downloaded from the server. You could of course hard code this information you'd suffer higher maintenance costs especially when supporting multiple languages.

The SparkleXRM Metadata Server allows dynamic expressions to be included in JavaScript Web Resources that are evaluated on the server and then cached on the client side.

Caching Metadata

Metadata (or data-about-data) can be evaluated on the server by including a Web Resource with the following name:

<schema>_/js/<name>.metadata.js

Where schema is your solution prefix and <name> is the name of your resources.
E.g..

new_/js/Res.metadata.js

If you have a resource that is specific to a particular locale (you might have static resource strings as well as dynamic) you can use:

[schema]_/js/<name>.metadata_[lcid].js

Where [lcid] is the locale of the language according to the language pack installed.

Note: Avoid having a name of ResourceStrings since this is a reserved word for Dynamics CRM Web Resources.
You can include both static and dynamic content. Enclose your dynamics expressions as follows:

/*metadata
var fieldLabel = <@contact.fullname.DisplayName@>;
metadata*/

This will output and cache the following on the client (for an LCID of 1033):

var fieldLabel = "Full Name";

Note: The /* commenting has been removed so that it will be evaluated. If the Metadata Server is not installed these enclosing comments prevent syntax errors when if resource is loaded.

Field Labels and Entity Names

To cache field labels include the following syntax:

ResourceStrings.contact_fullname_DisplayName = <@contact.fullname.DisplayName@>;
ResourceStrings.account_displayname = <@account.DisplayName@>;

This will output and cache the following on the client:

ResourceStrings.contact_fullname_DisplayName = "Full Name";
ResourceStrings.account_displayname = "Account";

Option Set Values

If you want to retrieve the option set values and labels you can use the following syntax:

ResourceStrings.quotedetail_shipto_ freighttermscode _OptionSet = <@quotedetail.shipto_freighttermscode.OptionSet@>;

This will output (for an LCID of 1033):

ResourceStrings.quotedetail_shipto_ freighttermscode_OptionSet = [{"value":1,"label":"FOB"},{"value":2,"label":"No Charge"}];

To provide these option set values to SparkleXRM so that the Grid Editor and Form Data Binders use it (rather than dynamically downloading when needed), use:

Xrm.Sdk.Metadata.MetadataCache.AddOptionsetMetadata('quotedetail','shipto_freighttermscode',true,<@quotedetail.shipto_freighttermscode.OptionSet@>);

Note: The Boolean parameter specifies if you want an empty null value in your option set.

Expressions templates

To save outputting the logical names twice in the names of your resource strings you can use an expression template:

//<@format=ResourceStrings.{1}_{2}_{3}={0}@>
<@account.DisplayName@>;
<@account.DisplayCollectionName@>;
<@account.name.DisplayName@>;

This will output (for 1033):

ResourceStrings.account_all_DisplayName="Account";
ResourceStrings.account_all_DisplayCollectionName="Accounts";
ResourceStrings.account_name_DisplayName="Account Name";

FetchXml Results

If you have configuration data that in frequently changes that you want to cache on the client and it is stored as a configuration entity in CRM, you can execute and cache the results of a FetchXml query:

var someFetchXml = <@fetch=<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" count="1">
<entity name="account">
<attribute name="name" />
<attribute name="accountid" />
<order attribute="name" descending="false" />
</entity>
</fetch>@>;

This will output the following:

var someFetchXml = {"totalRecordCount":"-1","Entities":[{"logicalName":"account","id":"c889707f-b5e2-e411-80d5-080027846324","name":"A. Datum Corporation (sample)","primarycontactid":{"logicalName":"contact","id":"2e8a707f-b5e2-e411-80d5-080027846324","name":"Rene Valdes (sample)"},"telephone1":"555-0158","accountid":{"id":"c889707f-b5e2-e411-80d5-080027846324"}}
]};

Cache Control

The Metadata server relies on Dynamics CRM’s excellent client side caching technique described in my blog article. Provide you use relative paths to access your web resources (or the cache key URL) the web resource will be downloaded once and then cached in the browser temporary internet files. This is then cached for 1 year before be re-downloaded and cached again.

Loading and Caching the SparkleXRM Metadata Web Resource

To dynamically download the metadata for the users selected language you can wrap the SparkleXRM View data binding in the following:

// Dynamically load the metadata from the server unless already cached on the client.
LocalisedContentLoader.FallBackLCID = 1033;
LocalisedContentLoader.SupportedLCIDs.Add(1033);
LocalisedContentLoader.SupportedLCIDs.Add(1031);
int lcid = (int)OrganizationServiceProxy.GetUserSettings().UILanguageId;
LocalisedContentLoader.LoadContent("new_/js/Res.metadata.js", lcid, delegate()
{
    InitLocalisedContent();
});

If the user's language is the same as the fall back LCID, then no resources are downloaded. If you need to always download the metadata you can add:

// Always download localised resources
LocalisedContentLoader.FallBackLCID = 0;

If the user's language does not match any of the Supported LCIDs, it will automatically fall-back to the default LCID. If you want to a load all languages you can add:

// Support all languages and do not restrict to only Supported LCIDs
LocalisedContentLoader.SupportedLCIDs.Add(0);

Forcing a cache-reload

If you make changes to metadata and require a re-load of all clients, you simply need to publish an update to the resource web resource. A good way of doing this is including a version number in the comments and then increment it and publish each time you require a cache re-load. The metadata will be re-evaluated the next time the client requests the web resource because it will have a different cache key:

http://server/Org/%7B634940089750000000%7D/WebResources/new_/js/Res.metadata_1033.js

To install the Metadata Server you need to simply download and import the SparkleXRM Metadata Server Solution from Github.,