Retrieve your CRM 2011 license key from the MSCRM_CONFIG database

It is probably not something you do daily, but sometimes you need to retrieve the CRM license key for a CRM installation.

In CRM 4.0 this could be done using:

  1. USE MSCRM_CONFIG
  2. SELECT LicenseKey FROM ConfigSettings

However, in 2011 this returns null. For reasons unknown Microsoft has created a new column to store the license key and the new query is:

  1. USE MSCRM_CONFIG
  2. SELECT LicenseKeyV5RTM FROM ConfigSettings

How to resolve timeouts when executing RetrieveAllEntitiesRequest

When you try to execute RetrieveAllEntitiesRequest to retrieve metadata for all the entities in your organisation you may receive the following error: “Message: The request channel timed out while waiting for a reply after 00:01:59.7655710. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.” Because of the large amount of data retrieved when executing RetrieveAllEntitiesRequest the default timeout value of 2 minutes is unlikely to be enough.

To increase the timeout value you need to set the timeout property on the OrganizationServiceProxy object. If you use the OrganizationServiceContext (as generated by CrmSvcUtil) you have to set the timeout on the OrganizationServiceProxy object you pass into the OrganizationServiceContext as there is no way to set the Timeout directly for the OrganizationServiceContext.

Of course timeouts can happen when you are doing other requests as well (and the solution is the same), but it is highly likely you’ll run into your first timeout issue when you start playing with the RetrieveAllEntitiesRequest request.

  1. using System;
  2. using System.Linq;
  3. using System.Net;
  4. using System.ServiceModel.Description;
  5. using Microsoft.Xrm.Sdk.Client;
  6. using Microsoft.Xrm.Sdk.Messages;
  7. using Microsoft.Xrm.Sdk.Metadata;
  8. namespace MetadataConsoleApplication
  9. {
  10.     class Program
  11.     {
  12.         static void Main(string[] args)
  13.         {
  14.             var organizationUrl
  15.                 = string.Format(
  16.                     “{0}/{1}/XRMServices/2011/Organization.svc”,
  17.                     http://{your_ip}”, “{organization_name}”);
  18.             var credentials = new ClientCredentials();
  19.             credentials.Windows.ClientCredential
  20.                 = new NetworkCredential(
  21.                   “{username}”, “{password}”, “{domain}”);
  22.             var serviceProxy
  23.                 = new OrganizationServiceProxy(
  24.                     new Uri(organizationUrl), null,
  25.                     credentials, null);
  26.             serviceProxy.ServiceConfiguration
  27.                 .CurrentServiceEndpoint.Behaviors.Add(
  28.                     new ProxyTypesBehavior());
  29.             // Increase the timeout to 30 minutes
  30.             // so the operation succeeds
  31.             serviceProxy.Timeout = new TimeSpan(0, 0, 30, 0);
  32.             var context = new AcmeContext(serviceProxy);
  33.             //  Retrieve metadata from CRM
  34.             var request = new RetrieveAllEntitiesRequest
  35.             {
  36.                 EntityFilters = EntityFilters.All,
  37.                 RetrieveAsIfPublished = true,
  38.             };
  39.             var response
  40.                 = (RetrieveAllEntitiesResponse)
  41.                     context.Execute(request);
  42.             Console.WriteLine(
  43.                 “Entities retrieved: “
  44.                 + response.EntityMetadata.Count());
  45.             Console.ReadKey();
  46.         }
  47.     }
  48. }

 

Create a plugin base class using generics

Once you start doing some serious plugin development with CRM 2011 you’ll probably start considering implementing a base class that implement common task you need to perform. If you create your base class in your plugin dll this is straightforward, but if you create a separate dll to contain your base class you’ll need to make sure your dll is deployed correctly as discussed previously.

However, as soon as you decide to use generics in your base class you’ll discover the story gets a bit more complicated.

Consider the following example base class and a plugin that implements the base class:
Base Class

  1. using System;
  2. using Microsoft.Xrm.Sdk;
  3.  
  4. namespace OG.Xrm.Plugins
  5. {
  6.     public class PluginBase<TEntity> : IPlugin
  7.          where TEntity : Entity, new()
  8.     {
  9.         public IPluginExecutionContext Context { get; private set; }
  10.         public IOrganizationServiceFactory ServiceFactory { get; private set; }
  11.         public IOrganizationService Service { get; set; }
  12.         public TEntity TargetEntity { get; private set; }
  13.  
  14.         /// <summary>
  15.         /// The execute method for the plug-in.
  16.         /// </summary>
  17.         /// <param name="serviceProvider">The execution context.</param>
  18.         void IPlugin.Execute(IServiceProvider serviceProvider)
  19.         {
  20.             Context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
  21.             ServiceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
  22.  
  23.             // Create service with context of current user
  24.             Service = ServiceFactory.CreateOrganizationService(Context.UserId);
  25.  
  26.             if (Context.InputParameters.Contains("Target"))
  27.             {
  28.                 // Get Updated Entity from parameter and convert to correct type
  29.                 var entityFromContext = (Entity)Context.InputParameters["Target"];
  30.                 TargetEntity = entityFromContext.ToEntity<TEntity>();
  31.             }
  32.  
  33.             Execute();
  34.         }
  35.  
  36.         /// <summary>
  37.         /// Child classes should override the execute method.
  38.         /// </summary>
  39.         public virtual void Execute()
  40.         {
  41.         }
  42.     }
  43. }

Plugin

  1. using OG.Xrm.Common;
  2.  
  3. namespace OG.Xrm.Plugins
  4. {
  5.    public class AccountPlugin : PluginBase<Account>
  6.     {
  7.        public override void Execute()
  8.        {
  9.            TargetEntity.Description = "Updated by Plugin";
  10.        }
  11.     }
  12. }

When registering the plugin with the plugin registration tool you’ll receive the following error: ERROR: Occurred while registering OG.Xrm.Plugins.AccountPlugin – Plug-in assembly does not contain the required types or assembly content cannot be updated

Luckily the solution for this problem is straightforward: simply implement the IPlugin interface explicitly in the AccountPlugin and the plugin will register and execute successfully.

  1. using OG.Xrm.Common;
  2. using Microsoft.Xrm.Sdk;
  3.  
  4. namespace OG.Xrm.Plugins
  5. {
  6.    public class AccountPlugin : PluginBase<Account>, IPlugin
  7.     {
  8.        public override void Execute()
  9.        {
  10.            TargetEntity.Description = “Updated by Plugin”;
  11.        }
  12.     }
  13. }

Custom Workflow Activities and Early Bound Entity Classes

In my previous post I wrote about some of the challenges with the CrmSvcUtil generated classes. As discussed in the post there is a solution to get the organisation service context class to work in a plugin. The next question is: does the same problem occur when using the service context class in a custom workflow activity?

To test this scenario I’m adding a custom workflow activity to the OG.Xrm.Plugins project created in the previous blog. The custom activity also selects the first contact and returns the full name of the contact in an output parameter. The CrmSvcUtil generated classes are in the OG.Xrm.Common project.

  1. using System.Activities;
  2. using System.Linq;
  3. using Microsoft.Xrm.Sdk;
  4. using Microsoft.Xrm.Sdk.Workflow;
  5. using OG.Xrm.Common;
  6. namespace OG.Xrm.Plugins
  7. {
  8.     public class CustomWorkflowActivity : CodeActivity
  9.     {
  10.         protected override void Execute(CodeActivityContext executionContext)
  11.         {
  12.             //Create the context
  13.             IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
  14.             IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
  15.             IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
  16.             var organisationContext = new CrmContext(service);
  17.             var contacts =
  18.                 from c in organisationContext.ContactSet
  19.                 select c;
  20.             FullnameOfFirstContact.Set(executionContext, contacts.First().FullName);
  21.         }
  22.         [Output("Fullname of First Contact")]
  23.         [Default("")]
  24.         public OutArgument<string> FullnameOfFirstContact { get; set; }
  25.     }
  26. }

After registering the activity using the plugin registration tool I can create a workflow containing just the custom workflow activity. When the workflow is executed it fails with the same error we have seen in the plugins: Object of type ‘Microsoft.Xrm.Sdk.Entity’ cannot be converted to type ‘OG.Xrm.Common.Contact’

error

As the error is the same as in the plugin example logically a similar solution should apply to fix the problem. In the case of the plugin this meant setting the ProxyTypesAssembly property for the context. However, there are some complications when trying to do this for a workflow.

The first step in cracking the problem is figuring out which class gets returned by

  1. executionContext.GetExtension<IWorkflowContext>()

By debugging the async service we can establish the class in question is the WorkflowContext class. This class is part of the Microsoft.Crm.Workflow.dll that can be found in C:\Program Files\Microsoft Dynamics CRM\Server\bin\

devbug

If I inspect this class using Reflector I can see the ProxyTypesAssembly property, but unfortunately Microsoft has decided to make both the WorkflowContext class and its base class WorkflowContextBase internal which means we can’t set use it in our own code to set the ProxyTypesAssembly from code. Why has Microsoft done this? Your guess is as good as mine, but hopefully this is something they’ll address in a rollup.

Luckily there is a solution using the magic of reflection. By using reflection we can set the ProxyTypesAssembly property even if the WorkflowContext class is internal. To achieve this we need to add the following highlighted lines of code to our custom activity:

  1. //Create the context
  2.             IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
  3.             IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
  4.            // This is where the magic happens          
  5.             var type = Type.GetType(“Microsoft.Crm.Workflow.SynchronousRuntime.WorkflowContext, Microsoft.Crm.Workflow, Version=5.0.0.0″);
  6.             type.GetProperty(“ProxyTypesAssembly”).SetValue(serviceFactory, typeof(CrmContext).Assembly, null);
  7.             IOrganizationServiceservice = serviceFactory.CreateOrganizationService(context.UserId);
  8.             var organisationContext = new CrmContext(service);
  9.             varcontacts =
  10.                 from c inorganisationContext.ContactSet
  11.                 selectc;
  12.             FullnameOfFirstContact.Set(executionContext, contacts.First().FullName);

Once we have recompiled and redeployed the plugin dll we can execute the workflow successfully.

Hope this helps!

Challenges with plugins and Early Bound Entity Classes

When CRM 2011 got released one of the things I was really excited about was CrmSvcUtil to generate Early Bound Entity Classes. In CRM 4 this option was sorely lacking and I ended up creating a custom tool to create my own wrapper classes. However, I prefer to let Microsoft do the hard work for me and was looking forward to using this tool.

If you follow the example in the CRM SDK you create a class project for your plugins and add the CrmSvcUtil generated class file to this project. To demonstrate the concept I’ll use a plugin that sets the correct casing for the first name, selects the first existing contact from the database and sets the job title of the new contact to the full name of the retrieved contact (the plugin is purely illustrational – I am not pretending to create a usable and/or logical plugin). The plugin is registered for the contact create.

  1. using System;
  2. using System.Linq;
  3. using Microsoft.Xrm.Sdk;
  4. namespace OG.Xrm.Plugins
  5. {
  6.     public class ContactPlugin : IPlugin
  7.     {
  8.         public void Execute(IServiceProvider serviceProvider)
  9.         {
  10.             var context = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext));
  11.             var entity = (Entity) context.InputParameters["Target"];
  12.             var contact = entity.ToEntity<Contact>();
  13.             contact.FirstName = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(contact.FirstName);
  14.             var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
  15.             var service = serviceFactory.CreateOrganizationService(context.UserId);
  16.             var organisationContext = new CrmContext(service);
  17.             var contacts =
  18.                 from c in organisationContext.ContactSet
  19.                 select c;
  20.             contact.JobTitle = contacts.First().FullName;
  21.         }
  22.     }
  23. }

At this point my plugin project contains two files: the contactplugin class and the CrmSvcUtil generated class.

vs_1

After registering the ContactPlugin for the contact create everything works as expected: the first name casing gets changed and the job title gets set correctly.

So far so good you might say, but the problem with this scenario is it only works for small projects. If you are working on a large Xrm implementation changes are you want to break up your project into separate dlls. I also want to avoid having multiple copies of the CrmSvcUtil generated class in my projects. For instance, I might like to break my project up into the following dlls:

  • OG.Xrm.Common – Containing the business logic and CrmSvcUtil generated model for my Xrm application referenced by all other dlls
  • OG.Xrm.Plugins – for my plugins
  • OG.XRM.WorkflowActivities – for custom workflow activities
  • OG.Xrm.Web – for custom web pages that might be part of the project
  • etc.

Now there are some challenges with creating your project like this. The most obvious one is that the CRM Solution Package does not allow you to include additional dlls that are referenced by your plugin assembly. There are various strategies to get around this problem and the “solution” Microsoft seems to be pushing the use ILMerge to merge your referenced dlls with your plugin dll. However, using ILMerge is a bit of a pain and (in my opinion) adds unnecessary complexity. If you are writing plugins for CRM Online this really is your only option, but in an on premise scenario you can deploy dlls referenced by your plugin assembly in the GAC.

Of course going down this path means you can’t rely on your CRM solution alone to deploy your full application: you’ll have to take care of deploying any additional dlls to the GAC. To me this is not a big problem as in my experience you usually end up with a number of artefacts that do not fit into the CRM solution anyway (for example console applications, aspx pages and custom WCF services). My preferred solution is to create a setup package that takes care of deploying all the bits and pieces that do not fit into the CRM solution and than deploys the CRM solution.

However, there is another challenge. If I rework my project and move the CrmSvcUtil model into a separate class project I’ll end up with this:

vs_2

If I deploy the OG.Xrm.Common dll to the GAC, update the Plugin and try to create a contact I will receive the following error: “Object of type ‘Microsoft.Xrm.Sdk.Entity’ cannot be converted to type ‘OG.Xrm.Common.Contact’

error

If you debug the code you’ll discover the error is thrown by the following line:

  1. contact.JobTitle = contacts.First().FullName;

Also notice how these lines execute without any problem: the problem only occurs once we start using the organizations service context class!

  1. var contact = entity.ToEntity<Contact>();
  2. contact.FirstName = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(contact.FirstName);

The problem seems to be that the OrganizationService that gets passed to organization service context class no longer recognizes the Early Bound Entity Classes in the separate dll. Luckily there is a (undocumented) solution for this problem: registering your Early Bound Entity Classes explicitly. To do this we have to change make the following changes in the OG.Xrm.Plugins project:

  1. Add the following references to the project (both dlls can be found in the C:\Program Files\Microsoft Dynamics CRM\Server\bin\folder):
    1. Microsoft.Crm.ObjectModel.dll
    2. Microsoft.Crm.Platform.Server.dll
  2. Add the highlighted line of code before getting calling the GetService method:
    1. ((IProxyTypesAssemblyProvider)context).ProxyTypesAssembly = typeof(Contact).Assembly;
    2. var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    3. varservice = serviceFactory.CreateOrganizationService(context.UserId);
    4. var organisationContext = new CrmContext(service);
    5. varcontacts =
    6. from c inorganisationContext.ContactSet
    7. selectc;
    8. contact.JobTitle = contacts.First().FullName;

Update your plugin and try again and this time the plugin will complete successfully.

UPDATE 19/04/2011:
Changed ((Microsoft.Crm.Extensibility.PipelineExecutionContext)Context).ProxyTypesAssembly = typeof(TServiceContext).Assembly;
to
((IProxyTypesAssemblyProvider)Context).ProxyTypesAssembly = typeof(TServiceContext).Assembly;

The original line only works with synchronous plugins, but throws an exception for asynchronous plugins. Using the IProxyTypesAssemblyProvider interface works for both synchronous and asynchronous plugins.

Start coding with Dynamics CRM Online and Early Bound Entity Classes in 6 easy steps

If you are like me most of your development probably has been with CRM On Premise and to be honest this is still my preferred option because it is less restrictive than developing for the cloud. However, the online version holds some tantalizing possibilities and I think the reality is that more and more clients will go for a cloud deployment in the near future.

Where CRM Online already shines is in the sales process. If I need to whip up a demo for a client I usually sign up for an online trial and start customizing as required. Recently I had to do a demo that involved interacting with the CRM services and surprisingly it is quite hard to find an easy example in the SDK or online. As the steps are a little more complex than in an on premise scenario I figured it was worth creating a little step-by-step tutorial.

Step 1 – Prerequisites
Make sure you have the following installed on your development environment:

Step 2 – Build and run the DeviceRegistration Tool

  • Open and build the deviceregistration.csproj file in {PathForCrmSDK}\sdk\tools\deviceregistration using Visual Studio.
  • Run the DeviceRegistration tool using: DeviceRegistration.exe /operation:register
  • Make a note of the Device ID and Device Password – you’ll need it in Steps 3 and 5.
    cmd

Step 3 – Generate the Early Bound Entity Classes using CrmSvcUtil.exe

  • Open a command prompt and navigate to {PathForCrmSDK}\sdk\bin\
  • Run CrmSvcUtil with the following options [replace highlighted sections with correct information for your CRM Online Instance]:
    CrmSvcUtil.exe /url:https://myorg.crm.dynamics.com/XRMServices/2011/Organization.svc /out:CrmProxy.cs
    /username:”myname@live.com” /password:”myp@ssword!” /serviceContextName:CrmOnlineContext
  • If everything goes correctly the tool will exit with: “Code written to C:\CRM\SDK\bin\GeneratedCode.cs

Step 4 – Create your Visual Studio Project

  • Open Visual Studio and create your project. For this example we’ll create a simple console app, but the steps are pretty much the same for other project types.
    vs1
  • In the project troperties make sure the target Framework is the .Net Framework 4 and not the .Net Framework 4 Client Profile:
    vs_2
  • Add the GeneratedCode.cs file to the project
  • Add the following references to the project [the first three dlls are located in {PathForCrmSDK}\sdk\bin\]:
    • microsoft.crm.sdk.proxy.dll
    • microsoft.xrm.client.dll
    • microsoft.xrm.sdk.dll
    • System.Runtime.Serialization.dll
    • System.Web.dll
    • System.Configuration.dll
  • Add an app.config file to the project
  • At this point your project should look like this (you might want to check if it builds as well):
    vs_4

Step 5 – Write some code

  • In the app.config add the Connection Strings section with a connection string for your CRM Online instance [make sure to replace the url, username, password, deviceid and devicepassword]:
    1. <?xmlversion=1.0?>
    2. <configuration>
    3.   <startup>
    4.     <supportedRuntimeversion=v4.0sku=.NETFramework,Version=v4.0/>
    5.   </startup>
    6.   <connectionStrings>
    7.     <addname=CrmOnlineconnectionString=Url=https://myorg.crm.dynamics.com;
    8.          Username=myname@live.com; Password=myp@ssword!;
    9.          DeviceID=MyDeviceId; DevicePassword=MyDevicePassword/>
    10.   </connectionStrings>
    11. </configuration>
  • Add the following usings in program.cs:
    1. using Microsoft.Xrm.Client;
    2. using Microsoft.Xrm.Client.Services;
  • In the main Method of program.cs add the following lines of code (notice the use of the very handy CrmConnection class):
    1. static void Main(string[] args)
    2. {
    3.     var connection = new CrmConnection(“CrmOnline”);
    4.     using (var serviceproxy = new OrganizationService(connection))
    5.     {
    6.         var context = new CrmOnlineContext(serviceproxy);
    7.         var contacts =
    8.             from c in context.ContactSet
    9.             select c;
    10.         foreach (var contact in contacts)
    11.         {
    12.             Console.WriteLine(contact.FullName);
    13.         }
    14.     }
    15.     Console.WriteLine(“Press any key to exit…”);
    16.     Console.ReadKey();
    17. }
  • Step 6 – Run your application

    • Press F5 to build and run your application. If everything went OK the console application will show the contacts stored in your CRM.

    That’s it! you are now all set to start writing code that interacts with the CRM Online Services.

Unblanking the Blank Screen

Aaah, the first blog post and the blank screen with the blinking cursor. What better recipe for instant writer’s block? How to fill the page with a vaguely interesting words that explain what the blog is going to be about and how it is going to add value in a world already saturated with blogs on any imaginable subject?

I guess I can start with explaining what this blog will be about: it won’t be about my hobbies [scuba diving, mountain biking], my daughter [even though there is plenty to tell about a feisty 15 month old] or my live in Sydney, Australia.

What this blog will be about is my daily experiences as a consultant working with Microsoft Dynamics CRM and related Microsoft technologies. While there are already a large number of blogs around I hope I can make my own small contribution and share some of my experiences.

My aim is to blog regularly and not fall in the “I’ve been busy lately and haven’t had time to blog” blog post trap. I’ll also try to find things reasonably entertaining and readable even though the content might be quite technical and dry at times.

On that note – enough for now. Let’s get cracking on the first real blog post.