When developing for CRM 2011 I’m pretty much always going to be setting the values of picklists (local and global optionsets), statecodes, statuscodes and booleans (two options) – the sorts of fields I’m talking about here are the ones highlighted in orange below. Usually I will know the label off the top of my head but I don’t always have the actual number value which is required to set the attribute correctly.
So usually I will open CRM up or use a metadata browser to find the actual value and then just hardcode it in – I don’t expect the optionset to change and if it does I will probably have to revisit the code to change more than just a hardcoded value.
However sometimes I cant be arsed with all that, sometimes I do need to find the value dynamically for a variety of reasons, e.g. laziness, convenience or occasionally an actual real requirement for it.
In any case here’s a function that when given an entity name and attribute name will return a dictionary of string labels (user localised) and corresponding int values. I won’t bother to go into any great detail on the code, but basically it just issues a RetrieveAttributeRequest, checks the AttributeType on the RetrieveAttributeResponse and then builds the dictionary.
static Dictionary<String, int> GetNumericValues(IOrganizationService service, String entity, String attribute) { RetrieveAttributeRequest request = new RetrieveAttributeRequest { EntityLogicalName = entity, LogicalName = attribute, RetrieveAsIfPublished = true }; RetrieveAttributeResponse response = (RetrieveAttributeResponse)service.Execute(request); switch (response.AttributeMetadata.AttributeType) { case AttributeTypeCode.Picklist: case AttributeTypeCode.State: case AttributeTypeCode.Status: return ((EnumAttributeMetadata)response.AttributeMetadata).OptionSet.Options .ToDictionary(key => key.Label.UserLocalizedLabel.Label, option => option.Value.Value); case AttributeTypeCode.Boolean: Dictionary<String, int> values = new Dictionary<String, int>(); BooleanOptionSetMetadata metaData = ((BooleanAttributeMetadata)response.AttributeMetadata).OptionSet; values[metaData.TrueOption.Label.UserLocalizedLabel.Label] = metaData.TrueOption.Value.Value; values[metaData.FalseOption.Label.UserLocalizedLabel.Label] = metaData.FalseOption.Value.Value; return values; default: throw new ArgumentOutOfRangeException(); } }
Then it’s pretty straight forward to use the label as a key to get the int value:
OptionSetValue optionSetValue = new OptionSetValue(GetNumericValues(proxy, "new_test", "new_local")["One"]);
So using the entity shown in the image, I can get all values for the various types of fields.