I’ve been meaning to write this post for a while. Even though CRM 4 is on the way out now, I still find myself working with clients that have legacy CRM 4 systems in production. Whether it is porting code or fixing bugs, CRM 4 is far from gone.

For those of you that don’t know, the DynamicEntity type gives us a way to write code against an arbitrary CRM4 installation without having to generate a custom service proxy. We don’t get the advantages of having all of the field names specified (early binding) but we don’t have to recompile for different client installations in order to get access to new fields.

However, despite of (or perhaps due to) the flexibility that DynamicEntities afford, there are some idiosyncratic things about how data property values are set and retrieved.

The hallmark of CRM 4 DyanmicEntities is the use of property classes for the data fields of the entity. These classes are all of the form XXXProperty, where XXX is something like String, CrmMoney, etc. CRM 2011 has largely done away with these special-purpose field wrappers, but in CRM 4 we are stuck with them. This wouldn’t be so bad, but there are some inconsistencies in their use in the Microsoft CRM API. I’ll go over a few cases that have bitten me in the past here.

1. Iteration

foreach( Property prop in m_entity.Properties ) {
    /// do something
}

When we use a foreach construct, the IEnumerator implementation returns a Property type. Why is this inconsistent? Well it isn’t from an API standpoint, but it was very confusing to me when I took a look at how the data was actually stored at runtime. Hint: there are no Property objects to be found in the backing store. They are created dynamically in the IEnumerator implementation. Take a look at the disassembly of IGetEnumerator():

private IEnumerator<Property> InternalGetEnumerator()
{
    List<Property> list = new List<Property>();
    foreach (KeyValuePair<string, object> pair in this._nameToPropertyValue)
    {
        list.Add(PropertyFactory.Instance.CreateInstance(pair.Key, pair.Value));
    }
    return list.GetEnumerator();
}

We can see that the Property types are actually being created and returned on-the-fly from the internal data store _nameToPropertyValue.

2. Assignment

We can do assignment in one of two ways. In each case the value that we assign will be slightly different.

DyanmicEntity entity = new DynamicEntity();
entity.Properties.Add( new StringProperty( key, value ) );

or

entity[ key ] = value;

This example also applies to retrieval of the property value, that is, if we want to get the plain string without the StringProperty wrapper we would write:

string val = entity[ key ];

I’ve noticed that when we make an assignment using a Property, the SDK library actually throws it away and only stores the inner value! This makes the property simply an ephemeral container that is effectively used only for conveying the field name. Check out disassembly for PropertyCollection.Add():

public void Add(Property property)
{
    this._nameToPropertyValue[property.Name] = property.GetValue();
}

So when iterating and using Add() we are dealing with Property types. When using [] indexer notation we are dealing with the underlying value data type. I find this to be quite inconsistent and tedious, but as long as it is kept in mind, things work out ok.

Hopefully this clears up some confusion about the finer points of DynamicEntities for you!


This is a topic that I’ve wanted to talk about for a while. Some time ago I implemented a quick dummy CRM service for testing out code without having to run a full CRM server. The initial version I wrote was for CRM4, and unfortunately by some oversight, MS did not actually implement ICrmService in their actual server API. This created an awkward situation where I had to wrap the “real” CrmService in my own shim that implemented the actual interface.

Fortunately CRM 2011 gets this right, so we no longer have to worry about that. In fact, MS has shown us how to implement our own IOrganizationService right in the sample code. Just look under samplecode\cs\client\soaplogger\soaplogger in the SDK. In the example, the SOAP requests are logged from the intermediate IOrganizationService implementation. However I have found using custom services to provide dummy data very useful for testing.

Eventually I fleshed out the mock CRM service and released it as FakeCRM.

I’ll be blogging more about this topic in the future, stay tuned!


I’m posting this list since it seems to be difficult for me to find quickly in the SDK documentation. It is an incredibly handy list of type mappings that are useful for converting CRM4 code to 2011 or for (in my case) writing abstraction libraries that need to convert between the two different CRM versions.

Without further ado, the list is here.

I’m including it inline here for quick reference:

AttributeTypeCode

Microsoft Dynamics CRM 2011 type

Microsoft Dynamics CRM 4.0 type

AttributeTypeCode.BigInt

long

N/A

AttributeTypeCode.Boolean

bool

CrmBoolean

AttributeType.CalendarRules

EntityCollection or CalendarRules[]

DynamicEntity[] or calendarrule[]

AttributeType.Customer

EntityReference

Customer

AttributeType.DateTime

System.DateTime

CrmDateTime

AttributeType.Decimal

decimal

CrmDecimal

AttributeType.Double

double

CrmFloat

AttributeType.EntityName

string

Attributes with ObjectTypeCode in DisplayMask

AttributeType.Integer

int

CrmNumber

AttributeType.Lookup

EntityReference

Lookup

AttributeType.ManagedProperty

BooleanManagedProperty

N/A

AttributeType.Memo

string

System.String

AttributeType.Money

 Money

CrmMoney

AttributeType.Owner

EntityReference

Owner

AttributeType.PartyList

 EntityCollection or ActivityParty[]

activityparty[] or DynamicEntity []

AttributeType.Picklist

OptionSetValue

Picklist

AttributeType. Uniqueidentifier (Formerly PrimaryKey)

System.Guid

Key

AttributeType.String

string

System.String

AttributeType.State

OptionSetValue or enumeration generated for the entity state

EntityNameStateInfo

AttributeType.Status

OptionSetValue

Status

AttributeType.Uniqueidentifier

System.Guid

UniqueIdentifier

AttributeType.Virtual

Not used in records.

Not used in records.


Hey guys, back after a bit of a break in blogging. I’ve been super busy on a lot of projects.

Here is a little tip that I found out about when I tried to consolidate my development environment a bit. I’m now running a CRM 2011 server on my dev machine. Unfortunately I also still need to support clients that are on CRM 4.0.

I didn’t think that this should be a problem since I have the 4.0 server on another box. However it seems that there is a conflict when the .NET runtime tries to locate the 4.0 SDK assembly. Since CRM 2011 supports backward compatibility by exposing support for the old SDK, it supplies its own version of Microsoft.Crm.Sdk.dll. The difference is that it is strongly signed with an updated version number of 5.0.0.0.

Here is the error that we get if we try to run a project compiled against the 4.0 SDK on a machine that has CRM 2011 installed (even though we are using the service endpoint of the CRM 4.0 server):

Error: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)		

We can force the runtime to load our own supplied version of Microsoft.Crm.Sdk by overriding the publisher policy. This is done in App.config (or Web.config for a web application) using the following code:

<configuration>
...
 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Crm.Sdk" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <publisherPolicy apply="no" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

That’s all there is to it. Now Fusion binding should find the correct assembly instead of trying to load the CRM 2011 out of the GAC.


Like me, I’m sure that many of you are consultants who have clients running on a trial version of the CRM software. Also, like me, you probably have a lot of CRM installations for testing.

Here is how you can update the product key in Microsoft CRM 2011. Get the new key from the client if it is a retail key that they purchased or grab a key from your MSDN subscription if it is one of your testing instances. Once you have the key, just open up the CRM Deployment Manager and look for the option hightlighted below:

Enter the key in the pop up window and enjoy life again!


I was writing some client code recently when I wanted to add a customer reference to a CRM campaignresponse entity instance. Using a simple EntityReference was giving me errors, so I looked to see what the data type was in CRM. Looking in the customisations screen, the type was ‘Party List’. The CRM SDK docs say that we should be able to use ActivityParty[] or EntityCollection for the field value.

The only info on ActivityParty that I found was for CRM4. Through trial and error I arrived at the following code:

Entity customer = new Entity("activityparty");
customer["partyid" ]= new EntityReference( "contact", in_contactID );
campaignResponse["customer"] = new EntityCollection( new List(){ customer } );

So what I had to do was create a list of entities that had an EntityReference field set that pointed to the contact. You cannot set the EntityReference directly on the campaignresponse, it is expecting an EntityCollection. Hopefully this saves you some time.


Starting with Windows Server 2008, Microsoft has stepped up its commitment to scriptable server management with the inclusion of PowerShell by default in the operating system. PowerShell enables the ease of scripting like batch files with the power of a scripting language like perl. Anyone that has done any extensive batch scripting will know what a pain it can be to do simple things like string handling.

Microsoft has doubled down on PowerShell in both CRM and SharePoint. Both are able to be managed using PowerShell snapins. What is a snapin? Snapins are what Microsoft calls script modules that can be loaded into PowerShell. The management features of CRM 2011 are supplied via a snapin.

The snapin will be installed on the CRM server by default, so to start powershell and load the snapin, we open up a console window and do the following:

C:\> powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator> add-pssnapin Microsoft.CRM.Powershell

Now we have access to all of the cmdlets (this is PowerShell terminology for a command tool).

For example, we can get information on the default CRM organization:


PS C:\Users\Administrator> get-crmorganization


BaseCurrencyCode      : USD
BaseCurrencyName      : US Dollar
BaseCurrencyPrecision : 2
BaseCurrencySymbol    : $
BaseLanguageCode      : 1033
DatabaseName          : crmtest_MSCRM
FriendlyName          : CRM Test
Id                    : 04721a7a-e0f5-45dc-a4b7-57e02088a13a
SqlCollation          : Latin1_General_CI_AI
SqlServerName         : WIN-0VODKV30814\SQL2008R2STD
SqmIsEnabled          : False
SrsUrl                : http://win-0vodkv30814/reportserver_sql2008r2std
State                 : Enabled
UniqueName            : crmtest
Version               : 5.0.9688.34
ExtensionData         : System.Runtime.Serialization.ExtensionDataObject

Here is a list of all of the available commands.