DLaB.Xrm.XrmToolBoxTools
DLaB.Xrm.XrmToolBoxTools copied to clipboard
Retrieve original option set values
Hello,
I have a generated option set used for Accounts that looks like this
[System.Runtime.Serialization.DataContractAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("CrmSvcUtil", "8.1.0.7711")]
public enum Account_IndustryCode
{
[System.Runtime.Serialization.EnumMemberAttribute()]
AgricultureForestryFishingMiningConstruction = 806860000,
[System.Runtime.Serialization.EnumMemberAttribute()]
CoalitionsConsortiums = 806860010,
[System.Runtime.Serialization.EnumMemberAttribute()]
Educationalproviders = 100000000,
[System.Runtime.Serialization.EnumMemberAttribute()]
FinanceInsuranceAndRealEstate = 806860003,
...
}
While the original displayed option set values look like this
Is there a way to get those values (Coalitions/Consortiums) either through querying CRM (using CrmServiceContext, not the static generated enum) or generating the code differently using this tool?
Thanks
I found this solution which doesn't use code generation
var raResponse = (RetrieveAttributeResponse)context.Execute(new RetrieveAttributeRequest
{
EntityLogicalName = "account",
LogicalName = "industrycode",
RetrieveAsIfPublished = true
});
var paMetadata = (PicklistAttributeMetadata)raResponse.AttributeMetadata;
// Get the current options list for the retrieved attribute.
var keyValues = paMetadata.OptionSet.Options.Select(o => new { Id = o.Value ?? 0, Name = o.Label.UserLocalizedLabel.Label });
which works well enough for me.
Your solution is the easiest way. "Coalitions/Consortiums" is not a valid C# Enum name. I could add an attribute that is the actual name of the Option set though... You could then use reflection to retrieve those string values, but that would be pretty far off from the standard CrmSvcUtil Enums, and I'm not sure I'm willing to perform that action...
Yup, that's what I was thinking exactly as the only reasonable generated-code solution, which I agree is probably too much since there is an alternate solution.
The enums are really meant for programmatic assignment of a specific value whereas here I'm trying to display values to end users.
Yep. And it's pretty easy to change the option set text value, which means the generated text values would be out of date anyway.
A solution I saw in another tool was to put the Label in as an Attribute:
public enum Address1_AddressType
{
///<summary><para>Bill To</para>
///<para>Value = 1</para></summary>
[Description("Bill To")]
BillTo = 1,
///<summary><para>Ship To</para>
///<para>Value = 2</para></summary>
[Description("Ship To")]
ShipTo = 2,
///<summary><para>Primary</para>
///<para>Value = 3</para></summary>
[Description("Primary")]
Primary = 3,
///<summary><para>Other</para>
///<para>Value = 4</para></summary>
[Description("Other")]
Other = 4
}
You can then retrieve the name using https://msdn.microsoft.com/en-us/library/71s1zwct(v=vs.110).aspx, although I guess a nice wrapper method around that would be nicer.
@craigseymour do you have a use case for this? Generally, I like to operate with the understanding, that people can change the text values of Option sets without ever affecting the system. This opens the door to a label change causing errors...
I don't have a strong use case - it was more a suggestion of a mechanism to address @sgwatgit's enquiry.
If I do have one is that I want to have a one-stop shop for everything I want to know about an Option Set without having to shell out to the OrganizationService. The downside, as you point out, is that the class is only a truthful representation of the Option Set at the moment it is generated.
But that applies to everything - the values, the labels, the order... So, as Option Sets are basically fragile anyway, I'm not sure that adding in the labels to the class makes it any worse :-)
As for introducing inaccuracies - My general assumption is that when the Option Set changes, I want the class to update too. If my enum name changes I want my compiler/unit tests to barf, otherwise the code might not be doing what I intended and probably doesn't read correctly anymore (depending of course what is has changed from and to!). If I'm foolish enough to use the Option Set label to apply logic, then I deserve what I get :-)
Especially when one considers localization...
I'm going to open this up as "help wanted" if anyone wants to implement this and send me a PR, I'll take it.
This was actually implemented with the Generate OptionSet Metadata option some time ago.