CRM Blog

Incorporating Custom Entities into a Plugin (revised)

by Mitchell Kett 03.19.08

Thanks to a reader's comment over my previous post, a small error has been brought to my attention and at the same time gave me an opportunity to improve and even go further into the process of using a custom entity within a plugin.

Microsoft.Crm.Sdk vs. CrmServiceWsdl 

Custom entities cannot be seen by the normal Microsoft.Crm.Sdk since it is a pre-compiled assembly that doesn't keep track of any changes you make to CRM.  Including the web reference to the CrmServiceWsdl (as explained in my previous post) makes all custom entities accessible.  However, it is not necessary to include a "using" statement for that web reference (You'll see why in the code provided later). 

DynamicEntity vs. DynamicEntity

Both the Sdk and Wsdl have their own respective DynamicEntity object, but the correct one to reference/use comes from the Sdk.  After eliminating the "using" statement for the Wsdl, you can declare a DynamicEntity and be assured that it is of type Microsoft.Crm.Sdk.DynamicEntity. 

Improved Code

//Standard references
using System;
using System.Collections.Generic;
using System.Text;
//References added by user
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Workflow;
using Microsoft.Crm.SdkTypeProxy;

namespace VehicleNamePlugin
{
    public class VehicleNameHandler : IPlugin
    {
        public void Execute(IPluginExecutionContext context)
        {
            DynamicEntity vehicle = null;

            //Check for entity to work with
            if (context.InputParameters.Properties.Contains("Target") &&
                context.InputParameters.Properties["Target"] is DynamicEntity)
            {
                vehicle = (DynamicEntity)context.InputParameters.Properties["Target"];
                //Check to make sure entity is a Vehicle entity
                if (vehicle.Name != VehicleNamePlugin.CrmServiceRef.EntityName.new_vehicle.ToString()) { return; }
            }
            else { return; }

            try
            {
               //Code to execute
               
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                throw new InvalidPluginExecutionException("An error occurred in the AccountCreateHandler plug-in.", ex);
            }

        }
    }
}

The above code takes the incoming DynamicEntity and checks to see if it is a new_vehicle (a custom entity created in CRM).  It is a carbon-copy of the code used in the sample plugin written in the SDK with the only change being the bolded text (which uses the Wsdl to grab the EntityName of the custom entity).

Registration

Say we want to fire off this plugin (even though it does nothing at the moment) after a new vehicle is created, but we can't find the new_vehicle within the EntityName list in the Registration Tool.  Luckily the SDK includes easy instructions on how to fix this.

Build the Visual Studio Solution

  1. Open the SDK\Tools\PluginRegistration folder and double-click the PluginRegistrationTool.sln file to open the solution in Visual Studio.
  2. In Solution Explorer, right-click the project name, PluginRegistration, and then click Add Web Reference.
  3. Enter the URL for the CrmService Web service in the form:

    http://<server:port>/mscrmservices/2007/CrmServiceWsdl.aspx

    Use the appropriate server name and TCP port for your Microsoft Dynamics CRM server.

  4. Enter a Web reference name of CrmSdk and click Add Reference.
  5. Repeat steps 3 and 4 for the CrmDiscoveryService Web service. Use a URL of http://<server:port>/mscrmservices/2007/AD/CrmDiscoveryService.asmx and name the Web reference CrmSdk.Discovery.
  6. Repeat steps 3 and 4 for the MetadataService Web service. Use a URL of http://<server:port>/mscrmservices/2007/MetadataService.asmx and name the Web reference MetadataServiceSdk.
  7. Compile the project by clicking Build, and then Build Solution. The executable file can be found in the bin\Debug folder of the project.
  8. If you are building and running the tool on a computer that is not a Microsoft Dynamics CRM 4.0 server, copy the Microsoft.Crm.Sdk.dll assembly from the SDK\Bin folder to the project's bin\Debug folder. The tool requires access to the Microsoft.Crm.Sdk.dll assembly in order to run.

Add the Tool to Visual Studio

You can register the Plug-in Registration Tool as an External Tool for Visual Studio.

  1. Open Visual Studio.
  2. Click on Tools | External Tools and then click on the Add button. If you have not yet added any tools, click on [New Tool 1].
  3. In the Title field, type CRM Plug-in Registration Tool.
  4. In the Command field, click the ellipsis button (…) and navigate to the bin\Debug\PluginRegistration.exe file that you built in the previous task. Click Open.
  5. Click OK.

You have now added the plug-in registration tool to the Visual Studio Tools menu.

Now that you've rebuilt the Plugin Registration Tool, you should now be able to see your custom entities in the EntityName list.  This may only get you started with custom entities and plugins, but it's definitely enough to spark some new ideas.

Filed under:

Comments

# George Doubinski said on March 19, 2008 12:33 PM:

Mitchell,

I'm still at loss why would you need to include your own reference?! You're dealing with DynamicEntity which does support your custom entities regardless of whether you include your wsdl or not. The line

if (vehicle.Name != VehicleNamePlugin.CrmServiceRef.EntityName.new_vehicle.ToString())

can be easily replaced with

if(vehicle.Name != "new_vehicle")

with the same effect minus custom reference.

If you believe that you can easily mix code from your reference and Microsoft.Crm.SdkTypeProxy, well, think again - all the types will clash and you won't be able to cast a thing.

As far as registration is concerned, the only extra bit you're getting is a "type-ahead" - you can still register your custom entity by typing its name manually. I trust you are getting latest plugin registration tool from code.msdn.microsoft.com/crmplugintool and not from SDK.

My 2c

# Mitchell Kett said on May 22, 2008 11:50 AM:

Apologies for such a late response.  George is quite right regarding the line replacement.  Now that I have looked into this deeper I can see that the use of the web reference is merely for use at design-time when you want to manipulate custom entities.  Assuming nothing changes with the entity, use of DynamicEntity is not necessary when using the web reference.  However, entities will frequently change, and to manipulate data from custom entities at runtime, DynamicEntity can be used.  DynamicEntity makes the web reference unneccessary since CRM handles it how the user defines it (give it type = 'account' and it'll be treated like an account... give it type = 'custom_object' and CRM will map it to a custom_object).

# Mitch Kett said on June 5, 2008 10:05 AM:

It has been asked whether or not the SDK can be "overriden" or "completed" in order to work with custom entities (thus getting around using the web ref and not having to use DynamicEntity), and as of right now I am not aware of such a thing.  If you are able to make CRM "update" the SDK with custom entity information, it's behavior and usage would be no different than the web ref.  In my opinion, it would be best to leave the SDK "as-is" simply because it would not be worth the time and effort to make it behave like the web ref which already exists.

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Security Check
Please answer the simple math problem below.

(required)