locked
Bulk Data import of contacts with option set data RRS feed

  • Question

  • Re: Dynamics CRM 2011...

    I wrote a quick console app to import Contact entity data from csv files:

    using(OrganizationServiceProxyserviceProxy = newOrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))

    {

    {

    IOrganizationServiceservice = (IOrganizationService)serviceProxy;

    using (StreamReader sr = File.OpenText(path)) { string s = ""; while ((s = sr.ReadLine()) != null) { Entity contact = new Entity("contact"); string[] contactData = s.Split(','); contact["firstname"] = contactData[0]; contact["lastname"] = contactData[1]; contact["new_state"] = contactData[2]; contact["emailaddress1"] = contactData[3]; contact["telephone1"] = contactData[4];...

    IOrganizationServiceservice = (IOrganizationService)serviceProxy;
    This fails on the Create but if I remove the code line which captures State ("new_state"), which is a custom field set up as an option set on CRM, it works fine. I used a tiny input file to test (2 contacts) and I double-checked to make sure the 2 states specified were in the option set list of 50 states ("MA" and "NY").

    The error message is "Incorrect attribute value type System.string"

    When I tried to create a data import map I also had a problem with option sets.

    Can someone explain what's going on?



    • Edited by MeProgrammer Friday, May 11, 2012 8:16 PM left out a line
    Friday, May 11, 2012 7:57 PM

Answers

  • There error comes because you are trying to convert list to optionMetadata.
    If you dont want to implement hard-coded option-set values please use
    Following block of code will give the Optioion value based on option name passed of the OptionSet

    static int GetOptionsSetValue(string entityName, string attributeName, string optionname)

    {

    RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest{

    EntityLogicalName = entityName,LogicalName = attributeName,RetrieveAsIfPublished =true};

    RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)ICommonLogic.GetService().Execute(retrieveAttributeRequest);

    PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (PicklistAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;

    OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();

    int optionValue = -1;

    foreach (OptionMetadata oMD in optionList)

    {

    if(oMD.Label.UserLocalizedLabel.Label == optionname)

    {

    optionValue = oMD.Value.Value;break;

    }

    }

    return optionValue;

    }
    For more help please check the following blog
    http://exploringxrm.wordpress.com/2011/08/19/29/


    I hope this helps. If my response answered your question, please mark the response as an answer and also vote as helpful.
    Mubasher Sharif
    Check out my about.me profile!
    http://mubashersharif.blogspot.com
    Linked-In Profile
    Follow me on Twitter!


    Monday, May 14, 2012 9:52 PM
  • MeProgrammer,

    Yep. That line should be response instead of retrieveAttributeResponse. I've updated the code to reflect that.

    You don't need to call metadata service. You can simply call the normal CRM Service and it should work.

    Feel free to mark my response as the answer.


    Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits

    Monday, May 14, 2012 10:44 PM

All replies

  • OptionSet has two things one is value and second is text.
    Please let me what are your storing in your CSV file the value of optionset(1ooooo) or Text(MA)
    This error comes because your are setting string instead of option set.

    Use the below code to set and import optionSetValue

    OptionSetValue optionState = new OptionSetValue();
    optionState.Value = contactData[2];
    contact["new_state"] = optionState;
    If it is text like MA or AK
    you need to implement a logic for this

    OptionSetValue optionState = new OptionSetValue();
    string contactStateText = contactData[2];
    if(contactStateText == "MA")
    { optionState.Value = 1; //Please check the values from CRM
    }
    else if(contactStateText == "AK")
    {
    optionState.Value = 2; //Please check the values from CRM
    } contact["new_state"] = optionState;

    If you need more information please let me know

    I hope this helps. If my response answered your question, please mark the response as an answer and also vote as helpful.
    Mubasher Sharif
    Check out my about.me profile!
    http://mubashersharif.blogspot.com
    Linked-In Profile
    Follow me on Twitter!





    Friday, May 11, 2012 8:41 PM
  • Thanks for responding, Mubasher.

    The csv file contains the actual US State names, e.g. "MA" or "AK".  I will try out what you suggested and get back to you on Monday.

    Friday, May 11, 2012 9:05 PM
  • MeProgrammer,

    Since your CSV file contains the actual US State names, firstly you will need to get the actual integer value of the OptionSet.

    Here is a bit of code to do that.

            RetrieveAttributeRequest request = new RetrieveAttributeRequest
            {
                EntityLogicalName = entityName,
                LogicalName = attributeName, // Your optionset schema name
                RetrieveAsIfPublished = true
            };
    
            RetrieveAttributeResponse response = (RetrieveAttributeResponse)crmService.Execute(request);
    
            if (response != null)
            {
                PicklistAttributeMetadata metadata = response.AttributeMetadata as PicklistAttributeMetadata;
                if (metadata != null)
                {
                    OptionMetadata[] optionsetList = metadata.OptionSet.Options.ToList();
                    foreach (OptionMetadata option in optionsetList)
                    {
                        if (option.Label.UserLocalizedLabel.Label == yourStateName)
                        {
                            int optionSetValue = optionsetMetaData.Value.Value; // This is the optionsetvalue that you want
                        }
                    }
                }
            }

    Once you get the optionset value, you can use it in your code

    contact["new_state"] = new OptionSetValue(optionSetValue); // Pass in the integer value that you get from previous code
    Hope this helps.



    Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits


    Friday, May 11, 2012 9:32 PM
  • Dimaz, thank you very much for providing that code!

    I am getting errors on PicklistAttributeMetadata,retrieveAttributeResponse, OptionMetadata[] and metadata.OptionSet.Options.ToList. 

    I added: using Microsoft.Xrm.Sdk.Metadata; which resolved the error on PicklistAttributeMetadata.

    Do I need to add References?  The retrieveAttributeResponse documentation says I need a web service called MetadataService but I don't know how to add that. Can you guide me?

    The error on metadata.OptionSet.Options.ToList says: "Cannot implicitly convert type 'Systems.Collections.Generic.List<Microsoft.Xrm.Sdk.Metadata.OptionMetaData> to 'Microsoft.Xrm.Sdk.Metadta.OptionMetadata[]'

    Also, since I was getting an error on PicklistAttributeMetadatametadata =retrieveAttributeResponse.AttributeMetadata as PicklistAttributeMetadata;
    I changed retrieveAttributeResponse.AttributeMetadata to response.AttributeMetadata

    Monday, May 14, 2012 2:03 PM
  • I did the following instead, modifying some code I found online:

     public static int GetOptionSetValueGivenText(IOrganizationService service, string entityName, string attributeName, string selectedValue)
            {
                try
                {
                    RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest { EntityLogicalName = entityName, LogicalName = attributeName, RetrieveAsIfPublished = true };
                    RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
                    PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (PicklistAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;
                    OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
                    int selectedOptionValue = 0;
                    foreach (OptionMetadata oMD in optionList)
                    {
                        if (oMD.Label.UserLocalizedLabel.Label == selectedValue)
                        {
                            selectedOptionValue = oMD.Value.Value;
                            break;
                        }
                    }
                    return selectedOptionValue;
                }
                catch (System.ServiceModel.FaultException ex1)
                {
                    string strEr = ex1.InnerException.Data.ToString();
                    return 0;
                }
    
            }

    This works.
    Monday, May 14, 2012 9:02 PM
  • There error comes because you are trying to convert list to optionMetadata.
    If you dont want to implement hard-coded option-set values please use
    Following block of code will give the Optioion value based on option name passed of the OptionSet

    static int GetOptionsSetValue(string entityName, string attributeName, string optionname)

    {

    RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest{

    EntityLogicalName = entityName,LogicalName = attributeName,RetrieveAsIfPublished =true};

    RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)ICommonLogic.GetService().Execute(retrieveAttributeRequest);

    PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (PicklistAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;

    OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();

    int optionValue = -1;

    foreach (OptionMetadata oMD in optionList)

    {

    if(oMD.Label.UserLocalizedLabel.Label == optionname)

    {

    optionValue = oMD.Value.Value;break;

    }

    }

    return optionValue;

    }
    For more help please check the following blog
    http://exploringxrm.wordpress.com/2011/08/19/29/


    I hope this helps. If my response answered your question, please mark the response as an answer and also vote as helpful.
    Mubasher Sharif
    Check out my about.me profile!
    http://mubashersharif.blogspot.com
    Linked-In Profile
    Follow me on Twitter!


    Monday, May 14, 2012 9:52 PM
  • MeProgrammer,

    Yep. That line should be response instead of retrieveAttributeResponse. I've updated the code to reflect that.

    You don't need to call metadata service. You can simply call the normal CRM Service and it should work.

    Feel free to mark my response as the answer.


    Dimaz Pramudya - CRM Developer - CSG (Melbourne) www.xrmbits.com http://twitter.com/xrmbits

    Monday, May 14, 2012 10:44 PM