Getting formatted value/label for OptionSetValue in early-binding

In the CRM SDK, when you retrieve the value of an Option Set attribute for an entity, only the integer value is returned. This is true for both early and late binding.

To retrieve the formatted value, i.e. the corresponding string label for the integer value, you would need to use the FormattedValues collection of the entity. For example, if we wanted to get the Preferred Contact Method for an account, this would look like this:

string preferredContactMethodLabel = entity.FormattedValues["preferredcontactmethodcode"];

This approach works for both early and late binding. However, you need to use the attribute’s logical name as a string, which defeats the purpose of early binding.

——————–

Update 17/09/2014: Be aware that in some cases the FormattedValues collection is not populated for the entity, for example for the Target entity of an Update plugin. This is true even if the Option Set field is one of the fields being updated. I have tested this with SP1 installed. The code below has been updated to handle this by returning an empty string. Under these scenarios, you’d need to retrieve the metadata of the field to retrieve the corresponding label.

——————–

To overcome this, I have developed an extension method on the Entity class that allows you to retrieve the formatted value of an Option Set attribute using a lambda. You’d use it like this:

string preferredContactMethodLabel = entity.GetFormattedValue(() => entity.PreferredContactMethodCode);

Just like early binding, the benefit of using a lambda is compiler checking. The lambda is also strongly typed to OptionSetValue, which means doing something like entity.GetOptionSetFormattedValue(() => entity.Name) would result in a compiler error.

public static class EntityExtension
	{
		public static string GetFormattedValue(this Entity entity, Expression<Func<OptionSetValue>> optionSetValueExpression)
		{
			Func<OptionSetValue> optionSetValueFunc = optionSetValueExpression.Compile();
			OptionSetValue optionSetValue = optionSetValueFunc();

			if (optionSetValue != null)
			{
				var optionSetAttributeName = entity.GetOptionSetAttributeName(optionSetValueExpression);
				return entity.FormattedValues.ContainsKey(optionSetAttributeName) ?
					entity.FormattedValues[optionSetAttributeName] : String.Empty;
			}
			return null;
		}

		public static string GetOptionSetAttributeName(this Entity entity, Expression<Func<OptionSetValue>> optionSetValueExpression)
		{
			string expressionString = optionSetValueExpression.ToString();
			int lastDotIndex = expressionString.LastIndexOf('.');

			string attributeName = lastDotIndex == -1 ? expressionString : expressionString.Substring(lastDotIndex + 1);
			return attributeName.ToLower();
		}
	}

This approach works base on the convention that the property names of the generated early binding types are the schema names of the entity attributes. Using Expression<Func> allows us to pass and perform string manipulation/interrogation on a lambda that is typed to OptionSetValue.

If the expression () => entity.PreferredContactMethodCode was passed, then optionSetValueExpression.ToString() would give the string below (Harness.Program is my test harness class), which allows us to extract the name of the attribute.

() => value(Harness.Program+<>c__DisplayClass0).entity.PreferredContactMethodCode

So there you have it, with a few simple extension methods you can improve your code quality, reduce chance of error, and keep your early-binding zen ;).

Advertisements

About Bernado

Based in Australia, I am a freelance SharePoint and Dynamics CRM developer. I love developing innovative solutions that address business and everyday problems. Feel free to contact me if you think I can help you with your SharePoint or CRM implementation.
This entry was posted in CRM. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s