MSCRM in Scotland

In the past I have had to explain to people that because you are filling in a seperate (non-customisable) form to mark an oppertunity as won then there is no way to tell what is happening to the opp as it is saved.

However while searching for something else I came across this article that details a very neat work around and one that I will be using in the future.

I have had cause to add values programmatically to a picklist in the contact entity. It is a custom picklist whose values change depending on actions on another entity. I struggled to pull together all the elements that I needed for this solution from areas on the net so I thought I would post this in case anyone faces a similar problem.

For a new picklist item you need a string to appear in the dropdown box and an integer that represents the choice in the entity.

The important thing to note is that you cannot edit the picklist directly. It is a concept I forget and struggle with sometimes when working with metadata that it exists in both a published and unpublished state. We use the InsertOptionValueRequest method to alter the picklist, adding an unpublished option to the list. If it were just to stay at that then the value would not appear until the next time someone published the entity, although you could see the value in the entity design screens. For clarity my two constants above that are declared elsewhere in the code are:

For performance I had put this code into a DLL in the GAC (it contains a library of actions I wanted in a single place) and is called by asynchronous process in a plugin. Having said that the action that fires it will be infrequent and may not actually happen once the system is provisioned and goes live. But either way I hope that I have mitigated any lag when the user clicks the Save button.

and an operational Plugin Registration (comes with the SDK) . Good guide here

I don't intend to go over creating a plugin from scratch, I use a VS template that builds the basic plugin library for me. Lazy I know but worth it. The templates are also in the SDK.

In this article I will cover off a simple requirement I have had. I need to relate a single entity to my contact entity and display it in an IFRAME. The IRFAME code is very simple and takes the custom entity object ID from a field in the contact record and uses that to build the frame URL.

So my steps are:

Create a new contact record

Create the related entity

Write the related entity ID to the contact record

The first step is simple enough. When a new contact record (in my example representing a student) is created the plugin is fired. I want this to be on the post-create event so that I can be sure that the student has passed all other validation before I create the finance record for them. This is achieved by registering the plugin as post stage thus

Of course we need some code to write first. We are going to get the contactid of the record, create a new custom entity type and save that to the CRM system.

So the first thing to cover off is the PostEntityImages call on the second line. This allows us to see what data we want in the final record. The registration tool gives us a really neat little window on this via the GUI. We register an image to the step (in this case I have called it "StudentDetails") and you can add or remove whatever fields you get. By default when you register an image it gives you all columns. Best practice is to remove everything and then explicitly add in what you need. In my case I want the contactid and the fullname fields

Then from the code

(DynamicEntity)context.PostEntityImages["StudentDetails"];

We can access the image we have created in the registration tool by simply passing the name to the collection of PostEntityImages casting it to DynamicEntity on the way back.

Second "Best Practice" element is how you interact with the contact entity. By default mine passes 28 fields to the plugin. If I were to add a field to this collection and pass it back for update that is a huge network overhead that on production environments could start to grind things down. In this case I have a method that takes in the entity type, the primary key name and value and returns a blank DynamicEntity for you to work with. The source was taken from Andrew Zimmer's blog on best practice.

This returns a DynamicEntity with the basiscs of what I need, the object type and a lookup to the contact record set. Once this has been created I add the contact.fullname into the custom entity (for seperate views I will use this to indicate what student it belongs to but will expand to include student number as the system develops). Once this is assigned we can create the finance object.

Guid financeKey = crmService.Create(finance);

The crmService.Create method returns the GUID of the object once it is created. I need this to link the IFRAME on my form so I am using this in a second step.

As this workingStudent object already has the primary key set calling the updated takes the new property and writes it back to the database without disturbing any other data.

And that is that. Following the creation of a student record my system automatically creates a finance account, storing the finance id back in the student record where I use it in an IFRAME to show the single entity with further sub-forms.

// Check if the InputParameters property bag contains a target// of the current operation and that target is of type DynamicEntity.if (context.InputParameters.Properties.Contains(ParameterName.Target) &&context.InputParameters.Properties[ParameterName.Target] is DynamicEntity){// Obtain the target business entity from the input parmameters.entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];if (entity.Name != EntityName.contact.ToString()){return;}}else{return;}

/// /// Returns a clone of the required entity but with only the primary key. You can then add/// the columns you are changing. Keeps network traffic down as only those columns being changed/// are sent back to the service./// /// /// /// /// private static DynamicEntity GetBlankEntity(string entityName, string primaryKeyAttribute, Guid id){DynamicEntity entity = new DynamicEntity(entityName);entity.Properties[primaryKeyAttribute] = new Key(id);return entity;}

MS CRM Blogs of Note

Followers

The content of this blog is my own work and do not represent the views of my employer, feel free to copy any code or ideas but please be aware that I provide no warranty, little support and accept no responsibility for anything bad that happens to you or your machines. NEVER apply anything you find on the Internet directly to a production machine because if you do you deserve everything you get ;)