Caching the Metadata

Making repetitive requests to the MetadataService Web service can have a negative impact on performance. Further, the metadata information does not change frequently. As such, many developers create a cache of the data retrieved from MetadataService inside their own applications.

Using the Timestamp

The RetrieveAllEntitiesResponse class has a Timestamp property that indicates the last time the metadata was updated. When building a cache you should compare the current timestamp with the one stored with your cache and refresh your cache appropriately. The timestamp can also be queried on the server using the RetrieveTimestampRequest. Developers should retrieve metadata using RetrieveAllEntitiesRequest and cache the RetrieveAllEntitiesResponse in their application. Periodically the application should then use RetrieveTimestampRequest to check for metadata updates. If the timestamp retrieved doesn’t match the timestamp in the cache, the cache can be invalidated and refreshed from CRM.

You will see a vast performance difference in retrieving the timestamp versus retrieving all entities in terms of operation time and server load. You should execute RetrieveAllEntities- Request sparingly.

Tip

Tip

Judiciously use the MetadataItems property of RetrieveAllEntitiesRequest. If your cache doesn’t require additional information, don’t retrieve it!

Example File System Cache

In this scenario, a basic console application has been programmed to store a cache of meta-data on the disk. Each time the application runs, it checks CRM to see whether the cache needs to be updated.

This basic example uses XML object serialization to store the metadata cache. The cache, in this example, is all entities in the organization. When the cache is first generated, it is saved to the disk. Each time the application checks the cache it first retrieves the timestamp from CRM and compares this to the timestamp in the cache. If the timestamps don’t match, the application retrieves the entity metadata from CRM and writes a new cache to the file system.

Example 8-2 displays the complete code for this application. The application will require appropriate Web Service WSDLs for the MetadataService and the CrmDiscoveryService.

More Info

More Info

See Chapter 15, for another sample of metadata caching.

Example 8-2. Sample metadata file system cache

using System;using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Example23.CrmDisco;
using Example23.CrmMeta;

namespace MetadataSample
{
    class Program
    {
        static void Main(string[] args)
    {
        #region Set Sample App Variables
        string orgName = "contoso";
        string discoveryServiceUrl =
            "http://crm/mscrmservices/2007/ad/crmdiscoveryservice.asmx";
        string metadataServiceUrl = string.Empty;
        string cachePath = "cache.xml";
        #endregion

        #region Check Metadata URL with the Discovery Service
        CrmDiscoveryService discoveryService = new CrmDiscoveryService();
        discoveryService.UseDefaultCredentials = true;
        discoveryService.Url = discoveryServiceUrl;
        RetrieveOrganizationsRequest retrieveOrgRequest = new
            RetrieveOrganizationsRequest();

        RetrieveOrganizationsResponse retrieveOrgResponse;
        retrieveOrgResponse = (RetrieveOrganizationsResponse)
            discoveryService.Execute(retrieveOrgRequest);

        foreach (OrganizationDetail orgDetail in
                 retrieveOrgResponse.OrganizationDetails)
        {
           if (orgDetail.OrganizationName == orgName)
           {
               metadataServiceUrl = orgDetail.CrmMetadataServiceUrl;
               break;
           }
        }
        #endregion

        #region Create Metadata Service Object
        CrmAuthenticationToken token = new CrmAuthenticationToken();
        token.AuthenticationType = 0;
        token.OrganizationName = orgName;
        MetadataService metadataService = new MetadataService();
        metadataService.CrmAuthenticationTokenValue = token;
        metadataService.UseDefaultCredentials = true;
        metadataService.Url = metadataServiceUrl;
        #endregion

        #region Creating Your Own Cache
        //Check the TimeStamp
        RetrieveTimestampRequest timestampRequest =
            new RetrieveTimestampRequest();
        RetrieveTimestampResponse timestampResponse;
        timestampResponse = (RetrieveTimestampResponse)
            metadataService.Execute(timestampRequest);

        //This object represents the Cache in memory
        RetrieveAllEntitiesResponse metadataCache =
            new RetrieveAllEntitiesResponse();

        //Does the Cache Exist?
        if (File.Exists(cachePath))
        {

             //Retrieve Cache the Cache
             metadataCache = RetrieveCache(cachePath);

             //Check Freshness of the Cache
             if (metadataCache.Timestamp != timestampResponse.Timestamp)
             {
                 File.Delete(cachePath);
                 metadataCache = CreateCache(cachePath, metadataService);
             }
         }
         else
         {
             //Create a New Cache
             metadataCache = CreateCache(cachePath, metadataService);
         }

         //Write the Logical Name of each entity to the Console
         foreach (EntityMetadata entity in metadataCache.CrmMetadata)
         {
             Console.WriteLine(entity.LogicalName);
         }
         #endregion
     }

     //Private Method to Retrieve the Metadata from CRM and Cache It
     private static RetrieveAllEntitiesResponse CreateCache(
         string cachePath, MetadataService metadataService)
     {
         RetrieveAllEntitiesRequest retrieveAllRequest =
             new RetrieveAllEntitiesRequest();
         retrieveAllRequest.RetrieveAsIfPublished = false;
         retrieveAllRequest.MetadataItems = MetadataItems.All;
         RetrieveAllEntitiesResponse retrieveAllResponse;
         retrieveAllResponse = (RetrieveAllEntitiesResponse)
             metadataService.Execute(retrieveAllRequest);

         Console.WriteLine("Retrieved from CRM");
         using (XmlWriter writer = XmlWriter.Create(cachePath))
         {
             XmlSerializer serializer =
                 new XmlSerializer(typeof(RetrieveAllEntitiesResponse));
             serializer.Serialize(writer, retrieveAllResponse);
         }
         return retrieveAllResponse;
      }

      //Private Method to Retrieve the Metadata from the Cache
      private static RetrieveAllEntitiesResponse RetrieveCache(string cachePath)
      {
          using (XmlReader reader = XmlReader.Create(cachePath))
          {
              XmlSerializer deserializer =
                  new XmlSerializer(typeof(RetrieveAllEntitiesResponse));
              return (RetrieveAllEntitiesResponse)
                  deserializer.Deserialize(reader);
          }
       }
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset