Salesforce .NET API: Get Picklist Values

Published on
-
4 min read

I have been doing a lot of Saleforce integration lately, which has been both interesting and fun. Throughout my time working on Salesforce, I noticed that I am making very similar calls when pulling information out for consumption into my website. So I decided to make an extra effort to develop methods that would allow me to re-use commonly used functionality into a class library to make overall coding quicker.

I am adding all my Salesforce object query related functionality to a class object called "ObjectDetailInfoProvider". This will give me enough scope to expand with additional methods as I see fit.

To start with, I decided to deal with returning all information from both picklist and multi-select picklists fields, since I find that I constantly require the values of data due to the vast number of forms I am developing. To be extra efficient in every request, I taken the extra step to cache all returned data for a set period of time. I hate the idea of constantly hammering away at an API unless absolutely necessary.

Before we get into it, it's worth noting that I am referencing a custom "AuthenticationResponse" class I created. You can grab the code here.

Objects

There are around seven class objects used purely for deserialization when receiving data from Salesforce. I'll admit I won't use all fields the API has to offer, but I normally like to have a complete fieldset to hand on the event I require further data manipulation.

The one to highlight out of all the class objects is "ObjectFieldPicklistValue", that will store key information about the picklist values, such as Label, Value and Active state. All methods will return this object.

public class ObjectFieldPicklistValue
{
    [JsonProperty("active")]
    public bool Active { get; set; }

    [JsonProperty("defaultValue")]
    public bool DefaultValue { get; set; }

    [JsonProperty("label")]
    public string Label { get; set; }

    [JsonProperty("validFor")]
    public string ValidFor { get; set; }

    [JsonProperty("value")]
    public string Value { get; set; }
}

I have added all other Object Field class objects to a snippets section on my Bitbucket account.

GetPicklistFieldItems() & GetMultiSelectPicklistFieldItems() Methods

Both methods perform similar functions; the only difference is cache keys and lambda expression to only pull out either a picklist or multipicklist by its field name.

/// <summary>
/// Gets a values from a specific picklist within a Salesforce object. Items returned are cached for 15 minutes.
/// </summary>
/// <param name="objectApiName"></param>
/// <param name="pickListFieldName"></param>
/// <returns>Pick list values</returns>
public static async Task<List<ObjectFieldPicklistValue>> GetPicklistFieldItems(string objectApiName, string pickListFieldName)
{
    string cacheKey = $"GetPicklistFieldItems|{objectApiName}|{pickListFieldName}";

    List<ObjectFieldPicklistValue> pickListValues = CacheEngine.Get<List<ObjectFieldPicklistValue>>(cacheKey);

    if (pickListValues == null)
    {
        Authentication salesforceAuth = await AuthenticationResponse.Rest();

        HttpClient queryClient = new HttpClient();

        string apiUrl = $"{SalesforceConfig.PlatformUrl}services/data/v37.0/sobjects/{objectApiName}/describe";

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiUrl);
        request.Headers.Add("Authorization", $"Bearer {salesforceAuth.AccessToken}");
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                
        HttpResponseMessage response = await queryClient.SendAsync(request);

        string outputJson = await response.Content.ReadAsStringAsync();

        if (!string.IsNullOrEmpty(outputJson))
        {
            // Get all the fields information from the object.
            ObjectFieldInfo objectField = JsonConvert.DeserializeObject<ObjectFieldInfo>(outputJson);

            // Filter the fields to get the required picklist.
            ObjectField pickListField = objectField.Fields.FirstOrDefault(of => of.Name == pickListFieldName && of.Type == "picklist");
                    
            List<ObjectFieldPicklistValue> picklistItems = pickListField?.PicklistValues.ToList();

            #region Set cache

            pickListValues = picklistItems;

            // Add collection of pick list items to cache.
            CacheEngine.Add(picklistItems, cacheKey, 15);

            #endregion
        }
    }

    return pickListValues;
}

/// <summary>
/// Gets a values from a specific multi-select picklist within a Salesforce object. Items returned are cached for 15 minutes.
/// </summary>
/// <param name="objectApiName"></param>
/// <param name="pickListFieldName"></param>
/// <returns>Pick list values</returns>
public static async Task<List<ObjectFieldPicklistValue>> GetMultiSelectPicklistFieldItems(string objectApiName, string pickListFieldName)
{
    string cacheKey = $"GetMultiSelectPicklistFieldItems|{objectApiName}|{pickListFieldName}";

    List<ObjectFieldPicklistValue> pickListValues = CacheEngine.Get<List<ObjectFieldPicklistValue>>(cacheKey);

    if (pickListValues == null)
    {
        Authentication salesforceAuth = await AuthenticationResponse.Rest();

        HttpClient queryClient = new HttpClient();

        string apiUrl = $"{SalesforceConfig.PlatformUrl}services/data/v37.0/sobjects/{objectApiName}/describe";

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiUrl);
        request.Headers.Add("Authorization", $"Bearer {salesforceAuth.AccessToken}");
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = await queryClient.SendAsync(request);

        string outputJson = await response.Content.ReadAsStringAsync();

        if (!string.IsNullOrEmpty(outputJson))
        {
            // Get all the fields information from the object.
            ObjectFieldInfo objectField = JsonConvert.DeserializeObject<ObjectFieldInfo>(outputJson);

            // Filter the fields to get the required picklist.
            ObjectField pickListField = objectField.Fields.FirstOrDefault(of => of.Name == pickListFieldName && of.Type == "multipicklist");

            List<ObjectFieldPicklistValue> picklistItems = pickListField?.PicklistValues.ToList();

            #region Set cache

            pickListValues = picklistItems;

            // Add collection of pick list items to cache.
            CacheEngine.Add(picklistItems, cacheKey, 15);

            #endregion
        }
    }

    return pickListValues;
}

Before you go...

If you've found this post helpful, you can buy me a coffee. It's certainly not necessary but much appreciated!

Buy Me A Coffee

Leave A Comment

If you have any questions or suggestions, feel free to leave a comment. I do get inundated with messages regarding my posts via LinkedIn and leaving a comment below is a better place to have an open discussion. Your comment will not only help others, but also myself.