Dynamics CRM 2013 Upgrade Gotcha: Sitemap Pointing to the Wrong Help?

July 31st, 2014

We’ve performed several sitemap customizations for clients in the past, so a recent MSDN article, Is your CRM 2013 pointing to CRM 2011 help?, really caught my eye. I admit that I don’t frequently use the online help for development, so learning that there are instances that a CRM upgrade can leave the help link pointing to the CRM 2011 page was a surprise.

The article has a great infographic that covers how to correct the issue, but it boils down to:

  1. Export a solution with the sitemap.
  2. Extract the files from the solution and open up the XML for the site map.
  3. Locate the “Help_Resource_Center” SubArea node and update the “Url” value to “http://go.microsoft.com/fwlink/?LinkId=296269″

And, while you’re in there, check if there are any other changes you should be making based on this TechNet article: Verify new areas are available in the navigation bar.

Generating Selected Entities for MS CRM Early Bound Entities

July 24th, 2014

On a recent project I had to create a web service that returned data from a MS CRM system based on provided parameters (account name and contact name). I prefer to work with the early bound, strongly typed XRM entities as opposed to using the web service calls, QueryExpression, ConditionExpression, etc., because the code is much shorter and easier to read – especially for anyone that has worked with Linq.

It takes a little more overhead to set up and create the XRM entities, though, and by default when you use crmsvcutil.exe it generates the early bound classes for every entity in the system. That’s a lot of overhead when you only need a small subset of entities like I did. In this case, I needed two entities: account and contact. I’ve had to do this before and always have to look up exactly how to do it. I have two blog posts that I’ve referenced when doing this. Both are very helpful, have actual code as well as a good explanation and wanted to share them. First is this post by Erik Pool. The second is this one by “Busy xRM Architects”. They both use a similar idea – read the entities to generate classes for from a file. One uses a text file and the other uses an XML file.

Hopefully this helps get the information out there and allows people to generate smaller classes!

Dynamics CRM 2013 Spring Release – Timer Control

July 3rd, 2014

One of the neater additions to CRM 2013 in the Spring ’14 Release is the ability to add a Timer control to a form. While it’s specifically mentioned that this new control can be used for service level agreements, the timer is generic enough that it can be used with any DateTime field in conjunction with a workflow to develop some handy time-dependent functionality. You just pick a DateTime field for it to look at, specify the Success/Waiting/Cancel Condition fields and values, then position it on the form.

There’s a great tutorial on how to add a Timer to the Lead form at Adding Timer Control to Lead Entity in Dynamics CRM 2013 Spring release, but I’d like to call out some things to keep in mind right here:

  1. The Success/Waiting/Cancel Condition fields can all be different.
  2. Only Option Set controls are available to select for the Condition fields.
  3. If you cannot add a Timer to the form because the Timer button is disabled, make sure that you’ve installed the latest product updates via the “Install Product Updates” link on the Administration page.

Getting the Current User Information in a Plugin

June 26th, 2014

I was working with MS CRM 2011 and I had a situation where I needed to get the information about the current user in the middle of plugin execution. When you start digging around the documentation in MS CRM you’ll find that there are two properties that look like they might have the information you need:

  • InitiatingUserId
  • UserId

Here’s an example of the code you’ll see in a plugin:

public void Execute(IServiceProvider serviceProvider)
{
    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

    // Which one is correct?
    var initiatingUserId = context.InitiatingUserId;
    var userId = context.UserId;
}

How do you know which one you need? What’s the difference? The difference is that the UserId property may or may not be the same as the InitiatingUserId. If in your plugin step registration “Run in User’s Context” field has the value “Calling User” then the UserId and InitiatingUserId will match. If you specify a user in the “Run in User’s Context” field, then the UserId field will contain the user ID of the person you specify and the InitiatingUserId will be the actual CRM user whose action triggered the plugin.

My bet is that most people are usually looking for the InitiatingUserId, so it probably makes sense to use that property even if you specify “Calling User” for the “Run in User’s Context” field. That way, if the “Run in User’s Context” value ever changes, InitiatingUserId will still have the correct value. If you use “UserID”, it’s possible you’ll get a different value than what you expect.

Hopefully this helps someone figure out which value is the correct one for your situation.

Knockout Select Value Binding

June 20th, 2014

I’ve used KnockoutJS with a few different projects and really like its two-way binding. However, one quirk I’ve ran into was binding to a select element. The select was bound to an array of Github repository objects and I wanted the selected item value to be the current repository object, not just one of its properties. For example, Listing 1 shows a sample repository and instead of the select value being say “id”, I wanted it to be the entire object.

{
	"id": 12015056,
	"name": "ApiRouter",
	"full_name": "OdeToCode/ApiRouter",
	"owner": {...},
	"private": false,
	"html_url": "https://github.com/OdeToCode/ApiRouter",
	"description": "Web API Message Handler, routes requests based segments",
	"fork": true,
	"created_at": "2013-08-10T03:38:36Z",
	"updated_at": "2014-03-25T02:13:06Z",
	"pushed_at": "2013-08-13T00:41:53Z",
	"size": 472,
	"stargazers_count": 0,
	"watchers_count": 0,
	"language": "C#",
	"has_issues": false,
	"has_downloads": true,
	"has_wiki": true,
	"forks_count": 0,
	"open_issues_count": 0,
	"forks": 0,
	"open_issues": 0,
	"watchers": 0,
	"default_branch": "master"
}

Listing 1. Sample Github repository object with selected properties

It’s a simple fix once you know what to do, but it wasn’t clear from the documentation how to do it.

When binding a select element to a Knockout view model, you can bind the “options”, “optionsText”, “optionsValue” and “value” attributes. Or you can bind the “options”, “optionsText” and “value” attributes. There are a few other attributes, but they don’t applied in this case.

If you bind a property to the the optionsValue attribute (which is what one would typically do), then the value attribute is also set to the same value as “optionsValue”. This is what’s not clear and can be confusing if both attributes are bound.

If your select is bound to an array of objects with just name and id properties, then setting “optionsText” to the name property and the “optionsValue” to the id property works just fine as “value” will also be set to the id property (see Listing 2).

<select data-bind="options: repos,
    optionsText: 'name',
    optionsValue: 'id',
    value: currentRepo">
</select>

Listing 2. Select element with only the optionsText, optionsValue and value attributes set

However, when your select element is bound to a array of objects with 3 more properties, it’s more likely that you want the current object when a selection is made, not just a particular property of the object. To get the current object as the value, only bind the “value” attribute, don’t use the “optionsValue” attribute as shown in Listing 3.

<select data-bind="options: repos,
    optionsText: 'name',
    value: currentRepo">
</select>

Listing 3. Select element with only the optionsText and value attributes set

With the simple change in Listing 3 in place, making a selection will now stored the current object as the “value” instead of just a particular property. Take at look at this Plunk to see an example of both scenarios.

For more info on Knockout’s binding, see the value binding and the options binding in the online documentation.

CRM 2013 Online and On-Premise: Organization Settings Editor

June 5th, 2014

While experimenting with CRM 2013′s new CRM app for Windows 8 and the iPad, we found that there were some limitations in place that were a bit restrictive for what we would like to see for some custom forms. For one of our clients, the Account form is particularly complex due to all the information they capture, so the default limit of 75 fields and 5 tabs wasn’t sufficient without significantly pruning the form. Of course, the tablet app uses the first available form for the logged in user, so removing fields/tabs from the form they would see by default in the browser was out of the question, even if we did want to display less information on the tablet.

The max number of fields and tabs on the tablet is configurable, though, and Sean McNellis’ Dynamics CRM Organization Settings Editor makes getting to these settings extremely painless. After importing the solution, it’s as easy as opening up the configuration page, clicking “Add” for the setting you wish to change, then editing the value for the setting. While caution should be used when changing any organization setting, this is a fantastic way for you to do it.

Click on the picture below to increase the size.

OrgSettingsEditor

More 2013 Client API Enhancements

May 29th, 2014

My co-worker Rod mentioned a nice CRM 2013 client SDK API change in his last post. Keeping up with the latest changes in various products can be quite a task given the number of tools we all have to work with as well as the rapid pace of changes to those tools. Sometimes a short video or document helps sort through what’s new. There’s short but very helpful video that outlines the new CRM 2013 client SDK features. Here are a few that I found interesting.

Those are just a few that jumped out at me. Watch the linked video for other items that have been added to the CRM 2013 client side SDK.

CRM 2013 Client API: Save & Refresh

May 23rd, 2014

Microsoft added some new methods to their JavaScript SDK for CRM 2013. The Xrm.Page.data.save() method now supports callbacks, which is quite handy. Salim Adamon has a nice short post on subject, so I’ve included it below.

In the past, using the old Xrm.Page.data.entity.save method caused a refresh of the page which dismissed any code after the save in your script. Take this scenario for example…

  • You have button in your ribbon on an Account form
  • The button calls an external web service to update some of the account field values based on the account’s Primary Contact value which is on editable on the form
  • The web service only takes the account id as a parameter, it loads the records, reads it and takes action

With the old save method, you had to require that the user saves the account so that the value of Primary Contact is saved to the database, then click your button that will call the web service with account ID. Such a requirement certainly causes pain in user experience especially if there are a lot of situations where they need to hit save, wait for refresh and click another button.

With the new Save and Refresh, we now have the possibility to add callback methods:

Xrm.Page.data.refresh(save).then(successCallback, errorCallback);

// Parameters
// save => A Boolean value to indicate if data should be saved after it is refreshed.
// successCallback => A function to call when the operation succeed
// errorCallbak => A function to call when the operation fails. It gets called with 2 parameters (an error code and a localized error message)

Xrm.Page.data.save().then(successCallback, errorCallback);

// Parameters
// successCallback => A function to call when the operation succeed
// errorCallbak => A function to call when the operation fails. It gets called with 2 parameters (an error code and a localized error message)

Having run into this issue in the past, makes this one a good candidate for the most exciting new client API feature for me.

See the following links for more information:
Microsoft Dynamics CRM 2013: Client API Enhancement
Microsoft Dynamics CRM 2013 SDK New Features – Client API (video)
CRM 2013 – Client API New Functionalities Recap
Microsoft Dynamics CRM 2013 Client API Cheat Sheet v1.1 (pdf)

Creating MS CRM Auto-Numbering

May 15th, 2014

We had a customer that wanted to have an auto-number field on an entity in MS CRM 2011. While CRM 2011 offers an out-of-the box numbering system for some entities, it’s not available for all entities. So, we came up with our own. There were several things it had to do:

  1. On an admin screen the user can:

    • Select an entity from a drop-down.
    • Enter/create a prefix for the entity.
    • Enter the starting number for the entity (if it has not been set).
    • Enter/create a suffix for the entity.
    • Specify the field for the entity that will contain the auto-generated/sequential number.
  2. When any record is created (account, contact, opportunity, etc.), a plugin:

    • Will determine if an auto-number record exists for that entity. If there is no auto-number record, the plugin stops executing.
    • Generate the auto-number
    • Update the record for the entity being created with the new autonumber.
    • Increment the auto-number on the admin entity with the next number.

To meet these goals, we came up with the following design:

Create a New Entity

A new entity, new_autonumber will need to be created with the following attributes:

  • Display Name: AutoNumber
  • Name: autonumber
  • Plural Name: AutoNumbers
  • Areas that display this entity: Settings

    • Options for entity – Communication and Collaboration – Unselect all (uncheck Notes, Activities, Connections, Mail Merge)
  • The entity will have the following attributes:
Display Name Name Type
Next Sequence Number new_NextSequenceNumber Whole Number; Min: 1, Max: default
Entity Name new_EntityName Single Line of Text; Max Length 64
Prefix new_Prefix Single Line of Text; Max Length 10
Suffix new_Suffix Single Line of Text; Max Length 10
Auto Number Field new_AutoNumberField Single Line of Text; Max Length 50
Auto Number Attempts new_AutoNumberAttempts Whole Number; Min: 1, Max : default
  • An entity can only be associated with one auto-number record. For example, there can only be new_autonumber record with the Entity Name of account.

Create a New Plugin

A new plugin will need to be created. This plugin can be registered on the create of any entity and fire after the records has been inserted. When registered, this plugin should use the following logic:

  • Determine if the entity type for the record being saved has an “AutoNumber” record associated with it.
  • If no AutoNumber record is associated with the current entity type, nothing further happens.
  • The plugin should read the AutoNumber record associated with the entity for the record that is being saved.
  • Using a lock (see http://msdn.microsoft.com/en-us/library/system.threading.monitor(v=vs.100).aspx) to ensure thread safety start a loop that goes from 1 to the value in the new_AutoNumberAttempts field:
    • Construct the auto-generated sequence number using the prefix, sequence number and suffix fields in the format:

      • Prefix-NextSequenceNumber-Suffix
      • If the prefix is blank then the hyphen that trails the suffix should not be used. If the suffix is blank then the hyphen prior to the suffix should not appear.
      • Examples of what various auto-generated values would look are below:
Prefix Suffix Next Sequence Number Generated Value
ACC XYZ 1003 ACC-1003-XYZ
ACC (blank) 1001 ACC-1001
(blank) (ACC) 1008 1008-ACC
(blank) (blank) 1009 1009
      • Update the new_NextSequenceNumber value by incrementing the value by 1.
      • Update the field designated by the value in the new_AutoNumberField  on the inserted entity record with the generated sequence number.
      • Query the database for the entity being inserted where the field specified new_AutoNumberField has the value of the generated sequence number and the ID is not equal to the value of the record just inserted. If the record count is 1, then break out of the loop.
      • If the count is > 1, then the field specified by the new_AutoNumberField needs to have its value set to null and the the loop should begin it’s next iteration.

Caveat

One of the major issues in generating a sequential number is ensuring that the code that generates the sequential number is only accessed by one thread at a time. On a single machine this can be accomplished by using the lock statement. With Microsoft CRM, though, there can be multiple servers that execute plugins. Since a lock only applies to a single app domain on a single server, a method is needed to attempt to make sure that two machines don’t attempt to use the same new_NextSequenceNumber value at the same time. The loop in the above code attempts to solve this problem by assigning the value and the checking to see if any other records have the same value. If there are other records that have the same value, the loop repeats until either a unique value is reached or it hits the maximum loop count.

If anyone has more foolproof ideas on how to create an auto-number when running more than one CRM server, we would love to hear them. We tossed around ideas of having a table with an identity column in it, inserting into it, getting the ID, and then deleting the record, but identity columns aren’t really supported in CRM. We though of doing the same thing but in a different database, but it seemed like a lot of overhead.

Conclusion

So there you have the outline of how we created an auto-number plugin. So far, it’s worked well for our customer with very few problems.

CRM 2013 Online and On-Premise: Handy Dev Tools

May 8th, 2014

I’ve always believed that most anything is possible, as long as you have the right tools. The holds true with Dynamics as much as it does with home repair or car maintenance, and having the right tools at your disposal can turn time-consuming dev tasks into trivial ones.

Daren Turner’s roundup of Dynamics CRM 2011 and 2013 useful Tools and Features bears reblogging, as he lists indispensable resources, such as the CRM SDK, tools that can help your everyday web development, like IE’s Developer Tools, and solutions that you can import into Dynamics to significantly speed up your dev time.

I’ve found two of those solutions particularly useful in my own development: the Ribbon Workbench and the OData Query Designer. Sure, you can mess around with the ribbon XML directly, if you like; the various nodes and attributes are well-documented in the Dynamics SDK. However, the Ribbon Workbench provides you with a WYSIWYG interface that can take the pain out of manually customizing the ribbon. As for the OData Query Designer, it’s just a quick and easy way to generate the strings needed to query the CRM web service from JavaScript, and is part of the Dynamics XRM Tools solution, which contains other handy tools as well.