My technical musings

Getting OptionSet values out of CRM2015 with C#

Every so often when you are reading a record in code the integer values from the OptionSet fields arent enough because you want to display the whole of the data contained in the record and make it fit for user consumption.

Unfortunately the only way is to pull out the OptionSet values from the fields separately and then do the comparison in code to find the correct text value, but making your own interfaces multilingual or populating your own lists for record creation then becomes quite straightforward.

A function like this will pull out a List of KeyValuePair containing the numeric value of the OptionSetValue and the text value local to the user who is running the code. It is quite easy to extend this to only pull out the text values for a specific user locale.

public static List<KeyValuePair<int, string>> getOptionSetText(IOrganizationService service, string entityName, string attributeName)
    List<KeyValuePair<int, string>> values = new List<KeyValuePair<int, string>>();
    RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest();
    retrieveAttributeRequest.EntityLogicalName = entityName;
    retrieveAttributeRequest.LogicalName = attributeName;
    retrieveAttributeRequest.RetrieveAsIfPublished = false;
    RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
    PicklistAttributeMetadata picklistAttributeMetadata = (PicklistAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;
    OptionSetMetadata optionsetMetadata = picklistAttributeMetadata.OptionSet;

    foreach (OptionMetadata optionMetadata in optionsetMetadata.Options)
        if (optionMetadata.Value.HasValue)
            values.Add(new KeyValuePair<int, string>(optionMetadata.Value.Value, optionMetadata.Label.UserLocalizedLabel.Label));
    return values;

To retrieve localised OptionSetValue text instead of using optionMetaData.Label.UnserLocalizedLabel.Label you could substitute it for something like

foreach (LocalizedLabel l in optionMetadata.Label.LocalizedLabels)
	string labelText = l.Label;
	int lang = l.LanguageCode;


This will loop around all the localised values to extract the text and the locale id code.