One of the most fascinating things I found during the creation of the CRM Migration Assistant is the different methods developers use to access CRM form fields, and other form elements.
Normally, people access a form field using the following style of JavaScript:
crmForm.all.name
This is the normal and perfectly acceptable (and supported) method for referencing CRM form fields.
But, for various reasons, I've also seen fields reference using these crmForm methods:
crmForm.name
crmForm.elements["name"]
crmForm.all["name"]
crmForm["name"]
This is perfectly acceptable JavaScript and the CRM 4.0 object model had no objection to this practice, so all of these methods seemed to work.
In fact, accessing CRM form fields using the JavaScript document object using these methods worked as well:
document.all("name_c")
document.all["name"]
document.getElementById("name_c")
The real question is: Will these methods continue to work when the organization is upgraded to CRM 2011?
The answer is: If you have used standard and supported methods within your JavaScript, then yes, the code will be supported.
This means referencing all of your form fields using the standard access model:
crmForm.all.name
Other options may or may not work correctly. Your experience my vary depending on which of the above methods were used.
Fortunately, the CRM Migration Assistant converts all of these "unsupported" form field access types into fully-supported CRM 2011 code using Xrm.Page.getAttribute and Xrm.Page.getControl, depending on how the field was being used.
If you haven't already, download the trial version of the CRM Migration Assistant and convert some of your questionable JavaScript through the conversion process.
If you run into any conversion issues, send me a code sample so that I can update the conversion process.
I learned some interesting things about working with Sandboxed plugins last week that I thought I'd share.
Attaching to Processes
Sandboxed plugins are run by Microsoft.Crm.Sandbox.WorkerProcess.exe so that is the process that you will need to attach to in order to debug your plugin. If there are more than one, then attach to all of them.
If there are none active in memory, perform whatever process that activates your plugin and the Sandbox HostService will activate at least one. Then you can attach to them.
If you are running a sandboxed plugin with an asynchronous step, you will also need to attach to CrmAsyncService.exe since this process is involved as well. More on that in a minute.
Using the Debugger
The Sandbox HostService only allows the WorkerProcess to process for 30 seconds. If it runs longer, it is terminated. This is a real problem when you're trying to look at data within the debugger and your code and data disappears in front of your eyes.
Add a DWORD key called SandboxDebugPlugins with a value of 1 to the MSCRM registry to prevent the process from being abnormally terminated.
Asynchronous Plugin Steps
A very interesting factoid is that if you have an asynchronous step inside of the sandbox plug, the processing of the step is different:
The CrmAsyncService.exe process will run your asynchronous step as it would any other async process but since it is from a sandboxed plugin, it will actually hand your plugin to the Sandbox process for execution.
This is why you must attach to both the Microsoft.Crm.Sandbox.WorkerProcess.exe and CrmAsyncService.exe in order to get the Visual Studio debugger to launch.
More Information
See this topic in the CRM SDK for more information.
One of the things that gets CRM 4.0 developers into trouble is moving customizations between organizations. Here is a tip that will prevent a lot of grief trying to troubleshoot some of the more confusing errors:
Always, Always, Always export all of your customizations from the source environment.
You can always import only the items that you are working on. The Import Customizations page allows you to select the items being imported.
Using this technique gives CRM all of the information about your customizations and schema so it it needs some secret little part of something, it is available.
Sometimes it will miss data or other relevant information and while not producing an error, may not fully recreate the customizations as you defined them within the source environment.
I have seen this appear as lost icons, invalid relationship connections, and just plain strange stuff that takes hours to find and fix.
An Example:
Last year, I ran into such a situation where we could not Publish All Customizations.
It took me about 6 hours to find and fix but the problem was related to a custom entity that was, well, broken. I had to manually insert a record into the database to fix it. ( and yes, that scared the crap out of me. )
It is my firm belief that this occurred because the person who installed the customizations only moved the four entities required from one organization to the other.
My initial solution was to export all customizations from the original source organization, import only those four entities into the development environment, then finish the remainder of the database cleanup manually.
This process had to be duplicated to the test and production organizations as well.
All in all, not a fun time and one that stretched my personal and professional expertise to the limit.
As I was reviewing notes from the recently released CRM SDK 5.0.9, I noticed a section on Error Codes. "This looks interesting," I thought.
After you have installed the CRM SDK, navigate to the following folder:
sdk\samplecode\cs\helpercode
In that folder you will find, among other things, three files related to error codes, each in a different format. It appears that there are around 2,015 error codes. Wow, that's a lot of documentation!
crmerrors.xlsx
Is a Microsoft Excel worksheet formatted like this:
errorcodes.cs
Is a C# class that has the error codes inside of a class that you can incorporate into your applications. The code starts off like this:
private static Hashtable ErrorMessages = new Hashtable();
static ErrorCodes()
{
ErrorMessages.Add(InvalidAuth,
"Organization Authentication does not match the current discovery service Role.");
ErrorMessages.Add(CannotUpdateOrgDBOrgSettingWhenOffline,
"Organization Settings stored in Organization Database cannot be set when offline.");
ErrorMessages.Add(InvalidOrgDBOrgSetting,
"Invalid Organization Setting passed in. Please check the datatype and pass in an appropriate value.");
ErrorMessages.Add(UnknownInvalidTransformationParameterGeneric,
"One or more input transformation parameter values are invalid: {0}.");
ErrorMessages.Add(InvalidTransformationParameterOutsideRangeGeneric,
"One or more input transformation parameter values are outside the permissible range: {0}.");
crmerrors.xml
The final version of the file is an XML which is formatted like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<crmerrors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<crmerror>
<ErrorId>
80048516
</ErrorId>
<ManagedErrorName>
InvalidAuth
</ManagedErrorName>
<ErrorMessage>
Organization Authentication does not match the current discovery service Role.
</ErrorMessage>
</crmerror>
<crmerror>
<ErrorId>
80048515
</ErrorId>
<ManagedErrorName>
CannotUpdateOrgDBOrgSettingWhenOffline
</ManagedErrorName>
<ErrorMessage>
Organization Settings stored in Organization Database cannot be set when offline.
</ErrorMessage>
</crmerror>
Regardless of how you use it, these files are a great resource for any CRM developer.
You may download it here.
This update includes:
|
New and updated topics |
Description of changes |
|
Microsoft_Dynamics_CRM_2011_SDK_Readme.htm |
Updated the readme for this version of the SDK package. |
|
SDK\Bin |
Updated the assemblies for Microsoft Dynamics CRM 2011 Update Rollup 6 and the Microsoft Dynamics CRM Online January 2012 Service Update. For on-premises customers, updates and hotfixes can be installed automatically from Microsoft Update. You can also search for updates on the Microsoft Download Center. For online customers, update rollups will be deployed automatically to your organization. |
|
SampleCode\CS\HelperCode\CrmErrors.xlsx SampleCode\CS\HelperCode\CrmErrors.xml SampleCode\CS\HelperCode\ErrorCodes.cs |
Updated error code files for this release. |
|
Tools\PluginRegistration |
Added federation and online federation provider types for Microsoft Office 365 support. In addition, fixed an issue that had occurred when configuring ACS. |
|
SampleCode\CS\* SampleCode\VB\* |
Updated all samples to use the GetOrganizationProxy helper method instead of instantiating OrganizationServiceProxy. This was done to add support for federated and managed Microsoft Office 365 organizations. For more information, see Active Directory and Claims-Based Authentication. |
|
Updated this topic and related topics to state that the Xrm.Page.context.getAuthenticationHeader function is deprecated and should not be used. Scripts upgraded from Microsoft Dynamics CRM 4.0 may continue to use the global getAuthenticationHeader function and should not be modified to use Xrm.Page.context.getAuthenticationHeader. New scripts using the REST endpoint for web resources or the SOAP endpoint for web resources do not require this function for authentication. |
|
|
Updated this topic to provide information that the EntityMetadata.CanCreateForms property controls whether new forms can be created for an entity. |
|
|
Included information about creating localized dialogs processes. |
|
|
Added a topic about Microsoft Dynamics CRM Online disaster recovery. |
|
|
Sample: Authenticate Users with Microsoft Dynamics CRM Web Services SampleCode\CS\GeneralProgramming\ SampleCode\VB\GeneralProgramming\ |
Added new samples that authenticate the user with the web services without using the helper code. |
|
Clarified that adding indexes is not supported for Microsoft Dynamics CRM Online. |
|
|
Use JavaScript with Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online |
Added a topic to help developers find information about using JavaScript with various features that support it. |
|
Removed reference in remarks to the refreshRibbon method that causes ribbon display rules to be re-evaluated. Only enable rules can be re-evaluated after the page loads. |
If you are developing a plugin, sooner or later you will need to do something in a plugin that requires "listening" to more than just Create, Read, Update, and Delete messages.
What is a Message?
If you are new to Dynamics CRM development, a Message word that is used to instruct CRM to do something. As far as I can tell, since the early versions of the CRM SDK used the SOAP protocol exclusively, and SOAP passes messages, the term message became the standard name for CRM internal processing options
If anyone has any other explanation, please let me know and I'll update the post.
What do you do with Messages?
Messages are what a plugin "listens for" to know when to activate and perform whatever job it was programmed to do.
A Message is associated with a Plugin Step ( internally called a SdkMessageProcessingStep ), which is a pointer that associates your plugin code to a Dynamics CRM internal action.
Inside the Plugin Registration Tool, you may see something like this:
As you can see, I have an assembly called ClassLibrary1, within that assembly I have a single plugin, SamplePlugin, and that plugin has two steps:
- Create of a queueitem
- Create of an email
Create is the Message.
How do I make it GO?
So, how do you, as a plugin developer, figure out what message you need to use to properly configure your plugin?
Well, for the most part, it's pretty simple: You select the CRM operation you are interested in intercepting then select Entity that will be associated with that Message.
Here is how the configuration looks within the Plugin Registration Tool:
But what if I don't know what message to use?
Excellent question, and the reason for my article.
The very fine folks in the Dynamics CRM documentation team have created for us, an Excel worksheet that lists all of the messages associated with a CRM Entity.
After you install the CRM SDK, you'll find the worksheet here:
sdk\tools\message-entity support for plug-ins.xlsx
And here is how it looks:
It lists the following information:
- Message Name
- Primary Entity
- Secondary Entity
- Message Availability
- Server or
- Both – for Client and Server
- Entity Supported Deployment
- Server or
- Both – for Client and Server
How do I use it?
Usually, I know what Entity I am going to work with so I start there and filter the Primary Entity based on that information.
Next, I try and locate the Message Name that I might need. Now this sounds simple, but in certain cases, it's really hard to determine what exact message you should connect with.
In that case, I will sometimes create steps that monitor each possible message, connect my debugger to IIS, then execute the CRM operation of interest so that I see what message is actually being passed through to my plugin.
You can find the message in the Execution Context's MessageName property.
Option 2
A second option is to look in the SDK help file itself for topics like:
Email (E-mail) Entity Messages and Methods
Where you will find information like this:
This should be the same (mostly) list of Messages found in the Excel file. Just remove the word "Request" from the end of the Message Name found in the SDK help file and you should have a match.
Conclusion
Well, that's about it for today. Hopefully this will help you in your plugin development efforts.
A CRM Organization's unique name is the name of the organization as it referred to internally. For example, it's the name of the SQL database.
Usually, the organization unique name is simply the Friendly Name with any illegal characters ( spaces, punctuation, etc. ) removed from the name.
For sample: CRM Accelerators is my friendly name, but crmaccelerators is my unique name.
There was a change introduced into CRM Online with Update Rollup 3 that made the unique name the Organization's Globally Unique Identifier ( GUID ) with the dashes removed.
While I doubt that this will affect to many people, it is a little disconcerting to see the unique name in that formation.
You can find the organization unique name under Settings, Customizations, Developer Resources you will see something like this:
Note: This is from an On-Premise organization.
Note: This is from an Online organization.
You can download it here.
For more information about this release, see Microsoft Knowledge Base article 2600640:
Update Rollup 6 is available for Microsoft Dynamics CRM 2011
To maintain parity between the application components of Microsoft Dynamics CRM 2011, this update rollup includes packages for Microsoft Dynamics CRM Server, Microsoft Dynamics CRM for Outlook, Microsoft Dynamics CRM Language Packs, and Microsoft Dynamics CRM E-mail Router.
That is the question.
A Universal App is one that will work on both the iPhone/iTouch and the iPad. One of the things that I've been considering from a design standpoint is the question of supported platforms for my apps.
For the app ideas that I've created, some apps are definitely platform specific, either iPhone or iPad, simply due to the amount of real estate required by the functionality I've designed. So those are really no-brainers.
Where the question gets fuzzy is with apps that could be used on either platform. Do I create platform-specific versions or do I create a universal app that can be used on either?
From a user prospective, it is more convenient to have a single app that runs on either platform, for the following reasons:
- It's cheaper since they only have to buy one copy.
- It can be less work assuming that data is stored in the cloud and is synchronized automatically. Their data just "shows up" on their device of choice.
However, it does increase the level of complexity when developing the app. A lot of the code can and should be organized in such a way that the device itself is irrelevant. The real deciding factor is in the View Controller.
My research has shown there seems to be two schools of thought:
1. Use a single view controller with code like this to make decisions about what to display:
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone)
{
homeScreen = new Screens.HomeScreen_iPhone();
}
else
{
homeScreen = new Screens.HomeScreen_iPad();
}
window.RootViewController = homeScreen;
2. Two view controllers that handle each device separately since the iPad has controls that are not available on the iPhone.
I do think it is a bad idea to create a "generic" application that only functions at the lowest common denominator. We need to use the functionality available to us for a specific device.
At this point in time, I really unsure of what my approach will be. I think I really need to start working on the code for one of the devices then see how much work it will be to actually implement it one way or the other.
If you have some experience and an opinion, or maybe just an opinion, I'd love to hear it.
In case you didn't know, Dynamics CRM 2011 has a basic mobile web site built into the product. You access the mobile site by adding /m to your CRM URL, like this:
Which will produce a web page that looks like this:
Here is what a view looks like:
and finally, record detail:
Now that we've seen it work, let's look at how to make it work.
Configuring the Mobile Experience
Configuring Dynamics CRM 2011 for mobile use is a multi-step process, which is as follows:
Step 1: Enable mobile support for the Entity
The first step is to actually enable mobile support at the Entity level, which you accomplish by checking the Mobile Express checkbox on the Entity's information page:
Click the Save button to record your changes.
Step 2: Update the Mobile form
Dynamics CRM 2011 includes a mobile form, as you can see from the Forms view:
Double-click the Mobile Information form to open it in the form editor.
If you are familiar with the normal CRM form editor you will notice that this is not it. Actually, you really can't do much with the form besides select what fields will be displayed.
This is accomplished by adding or removing fields from the Selected Attributes list on the right side of the dialog.
Like other CRM forms, you can assign roles to the form to show this only to certain types of people, if you wish.
Step 3: Publish your changes
After you have finished editing the mobile form, publish the Entity and your changes will be available to users.
Conclusion
That is about it for Mobile Express. It provides basic HTML-level access to CRM data through just about any mobile device.
However, should you need offline capabilities or a richer user experience, you might try a solution from a third-party vendor such as CWR Mobility, among others.




