6

I'm wondering how to get the string value of an OptionSet in a CRM plugin I am making. I thought all I had to do was pass the int value to OptionSetValue, but that doesn't seem to be working. Here is my code:

aBillingFrequencyCode = new OptionSetValue(myContract.BillingFrequencyCode.Value).ToString();

But the output is just

Microsoft.Xrm.Sdk.OptionSetValue

Any ideas?

shytikov
  • 9,155
  • 8
  • 56
  • 103
Mr Lahey
  • 656
  • 3
  • 15
  • 31

3 Answers3

21

You can retrieve OptionSet labels without retrieving all of the entity's metadata. I've provided two methods. One will use the language code (LCID) of the account that IOrganizationService is running under. The other allows you to specify the LCID.

Note, if you are going to use these extensively in code you may want to consider caching the value to improve performance - this will depend on your specific applications requirements.

If you plan to retrieve these values for multiple Option Sets on a single entity at the same time you should use Guido's code above and retrieve all the entity metadata in one call to reduce the number of calls you are required to make to CRM. Hence, each of our code snippets is more efficient in certain circumstances.

//This method will return the label for the LCID of the account the IOrganizationService is using
public static string GetOptionSetValueLabel(string entityName, string fieldName, int optionSetValue, IOrganizationService service)
{
    var attReq = new RetrieveAttributeRequest();
    attReq.EntityLogicalName = entityName;
    attReq.LogicalName = fieldName;
    attReq.RetrieveAsIfPublished = true;

    var attResponse = (RetrieveAttributeResponse)service.Execute(attReq);
    var attMetadata = (EnumAttributeMetadata)attResponse.AttributeMetadata;

    return attMetadata.OptionSet.Options.Where(x => x.Value == optionSetValue).FirstOrDefault().Label.UserLocalizedLabel.Label;
}

//This method will return the label for the specified LCID
public static string GetOptionSetValueLabel(string entityName, string fieldName, int optionSetValue, int lcid, IOrganizationService service)
{
    var attReq = new RetrieveAttributeRequest();
    attReq.EntityLogicalName = entityName;
    attReq.LogicalName = fieldName;
    attReq.RetrieveAsIfPublished = true;

    var attResponse = (RetrieveAttributeResponse)service.Execute(attReq);
    var attMetadata = (EnumAttributeMetadata)attResponse.AttributeMetadata;

    return attMetadata.OptionSet.Options.Where(x => x.Value == optionSetValue).FirstOrDefault().Label.LocalizedLabels.Where(l => l.LanguageCode == lcid).FirstOrDefault().Label;
}        
shytikov
  • 9,155
  • 8
  • 56
  • 103
Nicknow
  • 7,154
  • 3
  • 22
  • 38
  • 4
    I have seen examples of using `entity.FormattedValues["optionSet"]` to get the label of the selected option. Since I see far more people using the request service to retrieve this data I assume this is probably the way it should be done but I was just wondering, what are the differences? – Meiyoki Jul 25 '14 at 08:39
  • 1
    If you an entity you can use `entity.FormattedValues["optionSet"]` to get the option set label for the optionset value for that particular record. Your question read more generally as to how do I get the label for a particular option set value - not specific to the entity record - which is why I posted the code. – Nicknow Jul 25 '14 at 15:56
  • 1
    I'm not the OP, I was curious over best practices. – Meiyoki Jul 27 '14 at 01:48
  • 2
    You have to be aware of the origin in of your entity if you want to use the FormattedAttributes option. If you retrieve an entity using the organisation service you will find your value there, if it is a target retrieved from a plugin execution context your FormattedValue will not be present. If it is a PreImage/PostImage it will act similar to a record retrieved from the organisation service. – jhoefnagels Jun 05 '17 at 08:14
  • @jhoefnagels recently I used `string label = target.FormattedValues["resolutiontypecode"]` in a Plugin for Case Resolution - Create and it worked! (no image, no retrieving the entity) Seems it's improved since your comment. – Don Cheadle Oct 21 '21 at 22:39
7

In order to get the OptionSet text value you need to query the metadata (this because Dynamics CRM supports multiple languages)

Here an example:

public static string GetoptionsetText(string entityName, string attributeName, int optionSetValue, IOrganizationService service)
{
    string AttributeName = attributeName;
    string EntityLogicalName = entityName;
    RetrieveEntityRequest retrieveDetails = new RetrieveEntityRequest
    {
        EntityFilters = EntityFilters.All,
        LogicalName = EntityLogicalName
    };
    RetrieveEntityResponse retrieveEntityResponseObj = (RetrieveEntityResponse)service.Execute(retrieveDetails);
    Microsoft.Xrm.Sdk.Metadata.EntityMetadata metadata = retrieveEntityResponseObj.EntityMetadata;
    Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata picklistMetadata = metadata.Attributes.FirstOrDefault(attribute => String.Equals(attribute.LogicalName, attributeName, StringComparison.OrdinalIgnoreCase)) as Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata;
    Microsoft.Xrm.Sdk.Metadata.OptionSetMetadata options = picklistMetadata.OptionSet;
    IList<OptionMetadata> OptionsList = (from o in options.Options
                                            where o.Value.Value == optionSetValue
                                            select o).ToList();
    string optionsetLabel = (OptionsList.First()).Label.UserLocalizedLabel.Label;
    return optionsetLabel;
}
Guido Preite
  • 14,905
  • 4
  • 36
  • 65
0

That would be easy considering there is entity.FormattedValues["field_name"] you just need to identify the field type and get the string out of it.

var account = service.Retrieve("account",Guid.Parse(""),new ColumnSet(true));

var statcode = account.Attributes
    .Where(a => a.Value.GetType() == typeof(OptionSetValue) && a.Key == "statecode")
    .Select(f=> account.FormattedValues[f.Key])
    .First();

The above piece of code will identify Filter & fetch the statecode text from the account entity.

Vinod Srivastav
  • 3,644
  • 1
  • 27
  • 40