As you probably know, the State and Status options for a CRM entity are linked together. You can’t change the State options or values but you can change the Status options ( which are generally shown in a picklist ).
On a recent project, I needed to simulate the Cancel Opportunity dialog through a custom user interface. Rather than build a hard-coded list of reasons for the cancelation, I decided to use the CRM MetadataService to dynamically pull the data using the following method ( in C# ):
public SortedList RetrieveStatusList( string entityName, int statusValue) { SortedList list = new SortedList(); AttributeMetadata attMetaData; RetrieveAttributeRequest request = new RetrieveAttributeRequest(); request.EntityLogicalName = entityName; request.LogicalName = "statuscode"; RetrieveAttributeResponse response; response = (RetrieveAttributeResponse)metadataService.Execute(request); attMetaData = response.AttributeMetadata; StatusAttributeMetadata status = (StatusAttributeMetadata)attMetaData; foreach (StatusOption o in status.Options) { if (o.State.Value == statusValue) { list.Add(o.Label.UserLocLabel.Label, o.Value.Value.ToString()); } } return list; }
The method takes two parameters:
- The entity name
- The state code value
I am using this method to populate a ASP.NET dropdown list box using the following code:
DropDownList1.DataSource = RetrieveStatusList("opportunity", 2); DropDownList1.DataTextField = "Key"; DropDownList1.DataValueField = "Value"; DropDownList1.DataBind();
In the case of the Opportunity, we have the following State code values:
| Name | Value |
| Lost | 2 |
| Open | 0 |
| Won | 1 |
Since we are canceling an Opportunity, we use the Lost state, which has a value of 2.
How This Works
The key to making sense of this process is the StatusOption object. It contains data for both the Status Reason codes and the State with which are they associated.
Since we are looking for a specific state, we check the State for the Option and if it matches our expected value, we add it to the list.




