Click here to Skip to main content
15,884,986 members
Articles / Programming Languages / C# 3.5

Integrating your applications with MS CRM Online 2011 using C# SDK

Rate me:
Please Sign up or sign in to vote.
4.75/5 (7 votes)
5 Jun 2013CPOL2 min read 55.4K   19   3
This article provides helper code to quickly integrate your applications with CRM Online 2011 using C# SDK.

Introduction

Lately I have been writing a lot of code to integrate several systems with MS CRM Online 2011. The code snippets in this article will make your life a lot easier. This code has been well tested and does not use any deprecated APIs.

Background

MS CRM Online 2011 is a terrific product from Microsoft, it enables you to quickly create a fully integrated system for your organization. It scales very well in line with your organization's needs.

Microsoft Dynamics CRM Online Prerequisites

  • Download the Microsoft Dynamics CRM SDK.
  • You must be able to sign in to Microsoft Dynamics CRM Online
  • Microsoft Visual Studio 2010
  • Microsoft .NET Framework 4 or .NET 4.5
  • Install Windows Identity Foundation if using .NET Framework 4; Pre-installed in .NET Framework 4.5

SDK Library references

All the code used in this article references microsoft.xrm.sdk.dll, which can be found in the bin directory after installing the CRM SDK.

Connecting to CRM Online via C# code

This code snippet can be used to connect to CRM online and create a new Entity. This code also handles duplicate detection via the exception code.

C#
public void Create(Zenbus.IT.ControlCenter.CoreData.BTS.Message message)
{
    // --------------------------- Invoke Proxy code ------------------------
    ClientCredentials Credentials = new ClientCredentials();
    Credentials.UserName.UserName = CoreData.BTS.ExternalConfiguration.CrmOnlineUserName;
    Credentials.UserName.Password = CoreData.BTS.ExternalConfiguration.CrmOnlinePassword;

    // https://cbb720.api.crm.dynamics.com/XRMServices/2011/Organization.svc

    Uri OrganizationUri = new Uri(string.Format(@"https://{0}{1}/XRMServices/2011/Organization.svc", 
        CoreData.BTS.ExternalConfiguration.OrgName, CoreData.BTS.ExternalConfiguration.ServerName));
    Uri HomeRealmUri = null;

    using (OrganizationServiceProxy serviceProxy = 
           new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))
    {
        CreateRequest request = new CreateRequest();
        request.Target = CRMObjectMapper.CRMMessage(message);
        request.Parameters["SuppressDuplicateDetection"] = false;

        try
        {
            serviceProxy.Execute(request);
            System.Diagnostics.Debug.Write(string.Format("Added new : {0}", 
                   request.Target.LogicalName), EVENT_CATEGORY);
        }
        catch (FaultException<OrganizationServiceFault> fault)
        {
            if (fault.Detail.ErrorCode == -2147220685)
            {
                System.Diagnostics.Debug.Write("Duplicate detected. Reason: " + 
                       fault.Reason.ToString(), EVENT_CATEGORY);
            }
            else
            {
                throw;
            }
        }
    }

    System.Diagnostics.Debug.Write("Create() complete.", EVENT_CATEGORY);
}

This line of code CRMObjectMapper.CRMMessage(message); returns an Entity object. This is how a CRM Entity can be created using the late binding syntax.

cs#
public static Entity CRMMessage(Zenbus.IT.ControlCenter.CoreData.BTS.Message messageInstanceData)
{
    // Handle
    Entity entityInstance = new Entity("zen_message");
    // Assigning message ID to zen_name deliberately
    entityInstance["zen_name"] = messageInstanceData.MessageID;
   
    // Counts
    entityInstance["zen_messagepartcount"] = Int32.Parse(messageInstanceData.MessagePartCount);
    entityInstance["zen_messageretrycount"] = Int32.Parse(messageInstanceData.MessageRetryCount);
    return entityInstance;
}

Fetching the Entity ID of a newly created Entity

This code snippet can be used to retrieve the Entity ID GUID for a newly created Entity or an existing one. Notice the QueryExpression, you might have to change it to suit your requirement.

C#
public static Guid GetEntityID(string entityName, 
       string columnName, string columnValue, string guidColumnName)
{
    // --------------------------- Invoke Proxy code ------------------------
    ClientCredentials Credentials = new ClientCredentials();
    Credentials.UserName.UserName = CoreData.BTS.ExternalConfiguration.CrmOnlineUserName;
    Credentials.UserName.Password = CoreData.BTS.ExternalConfiguration.CrmOnlinePassword;

    // https://cbb720.api.crm.dynamics.com/XRMServices/2011/Organization.svc

    Uri OrganizationUri = new Uri(string.Format(
        @"https://{0}{1}/XRMServices/2011/Organization.svc", 
        CoreData.BTS.ExternalConfiguration.OrgName, CoreData.BTS.ExternalConfiguration.ServerName));
    Uri HomeRealmUri = null;

    using (OrganizationServiceProxy serviceProxy = 
           new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))
    {
        QueryExpression query = new QueryExpression()
        {
            EntityName = entityName,
            ColumnSet = new ColumnSet(guidColumnName),
            TopCount = 1,
            Criteria =
            {
                Conditions =
                    {
                        new ConditionExpression (columnName, ConditionOperator.Equal, columnValue)
                    }
            }
        };

        DataCollection<Entity> entityCollection = serviceProxy.RetrieveMultiple(query).Entities;

        if (entityCollection.Count > 0)
        {
            return entityCollection[0].Id;
        }
        else
        {
            System.Diagnostics.Debug.Write(string.Format(
              @"GUID NOT found for entity: {0}, value: {1}, column:{2}, ", 
              entityName, columnValue, columnName), EVENT_CATEGORY);
            return System.Guid.Empty;
        }
    }
}

Getting CRM OptionSet text by value

In several cases you might want to get the OptionSet text, given a value. The code snippet below helps you to get it.

C#
public static string GetOptionSetTextByValue(
       string entityName, string attributeName, int selectedValue)
{
    // --------------------------- Invoke Proxy code ------------------------
    ClientCredentials Credentials = new ClientCredentials();
    Credentials.UserName.UserName = CoreData.BTS.ExternalConfiguration.CrmOnlineUserName;
    Credentials.UserName.Password = CoreData.BTS.ExternalConfiguration.CrmOnlinePassword;
    // https://cbb720.api.crm.dynamics.com/XRMServices/2011/Organization.svc
    Uri OrganizationUri = new Uri(string.Format(
        @"https://{0}{1}/XRMServices/2011/Organization.svc", 
        CoreData.BTS.ExternalConfiguration.OrgName, CoreData.BTS.ExternalConfiguration.ServerName));
    Uri HomeRealmUri = null;
    using (OrganizationServiceProxy serviceProxy = 
           new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))
    {
        RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest
                                                                    {
                                                                        EntityLogicalName = entityName,
                                                                        LogicalName = attributeName,
                                                                        RetrieveAsIfPublished = true
                                                                    };
        // Execute the request.
        RetrieveAttributeResponse retrieveAttributeResponse = 
          (RetrieveAttributeResponse) serviceProxy.Execute(retrieveAttributeRequest);
        // Access the retrieved attribute.
        Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata 
          retrievedPicklistAttributeMetadata = (Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata)
        // Get the current options list for the retrieved attribute.
        retrieveAttributeResponse.AttributeMetadata;
        OptionMetadata[] optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
        string selectedOptionLabel = string.Empty;
        foreach (OptionMetadata omd in optionList)
        {
            if (omd.Value == selectedValue)
            {
                selectedOptionLabel = omd.Label.UserLocalizedLabel.Label;
                break;
            }
        }
        return selectedOptionLabel;
    }
}

How to associate N-N relationship via the SDK

The code snippet below helps you to associate an N-to-N relationship between Entitys via the CRM SDK code.

C#
public static bool Associate_N2N_EntityRecords(
    Microsoft.Xrm.Sdk.EntityReference parentReference,
    Microsoft.Xrm.Sdk.EntityReference childReference, string relationshipName)
{
    ClientCredentials Credentials = new ClientCredentials();
    Credentials.UserName.UserName = CoreData.BTS.ExternalConfiguration.CrmOnlineUserName;
    Credentials.UserName.Password = CoreData.BTS.ExternalConfiguration.CrmOnlinePassword;
    Uri OrganizationUri = new Uri(string.Format(
        @"https://{0}{1}/XRMServices/2011/Organization.svc", 
        CoreData.BTS.ExternalConfiguration.OrgName, CoreData.BTS.ExternalConfiguration.ServerName));
    Uri HomeRealmUri = null;
    using (OrganizationServiceProxy serviceProxy = 
           new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))
    {
        AssociateRequest associateRequest = new AssociateRequest
        {
            Target = new EntityReference(parentReference.LogicalName, parentReference.Id),
            RelatedEntities = new EntityReferenceCollection
            {
                new EntityReference(childReference.LogicalName, childReference.Id)
            },
            Relationship = new Relationship(relationshipName)
        };
        serviceProxy.Execute(associateRequest);
    }
    return true;
}

How to quickly add Annotations to your Entity

The code snippet below helps you to quickly add Annotations. Note that this code returns an annotation Entity object.

C#
public static Entity CRMOrchestrationAnnotation(EntityReference parentReference, string orchestrationImagePath)
{
    FileInfo fileInfo = new FileInfo(orchestrationImagePath);
    byte[] imageArray = new byte[fileInfo.Length];
    var fileStream = fileInfo.OpenRead();
    fileStream.Read(imageArray, 0, (int)fileInfo.Length - 1);
    // Handle
    Entity entityInstance = new Entity("annotation");
    entityInstance["filename"] = fileInfo.Name;
    entityInstance["mimetype"] = @"image/jpeg";
    entityInstance["documentbody"] = Convert.ToBase64String(imageArray);
    entityInstance["objectid"] = parentReference;
    entityInstance["subject"] = "Orchestration Image";
    entityInstance["notetext"] = String.Format("{0:F}", DateTime.Now);  
    return entityInstance;
}

How to update an existing Entity in CRM

This code snippet helps to update an existing Entity. If the Entity is not found, it creates it.

C#
public void Update(Zenbus.IT.ControlCenter.CoreData.BTS.Orchestration artifact)
{
    // --------------------------- Invoke Proxy code ------------------------
    ClientCredentials Credentials = new ClientCredentials();
    Credentials.UserName.UserName = CoreData.BTS.ExternalConfiguration.CrmOnlineUserName;
    Credentials.UserName.Password = CoreData.BTS.ExternalConfiguration.CrmOnlinePassword;

    // https://cbb720.api.crm.dynamics.com/XRMServices/2011/Organization.svc

    Uri OrganizationUri = new Uri(string.Format(
      @"https://{0}{1}/XRMServices/2011/Organization.svc", 
      CoreData.BTS.ExternalConfiguration.OrgName, CoreData.BTS.ExternalConfiguration.ServerName));
    Uri HomeRealmUri = null;

    using (OrganizationServiceProxy serviceProxy = 
           new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))
    {
        try
        {
            // Retrieve the entity and its attributes.
            Entity updatedEntity = CRMObjectMapper.CRMOrchestration(artifact);
            updatedEntity.Id = CRMBase.GetEntityID("zen_orchestration", 
              "zen_name", artifact.Name, "zen_orchestrationid");

            if (!updatedEntity.Id.Equals(Guid.Empty))
            {
                UpdateRequest request = new UpdateRequest();
                request.Target = updatedEntity;

                serviceProxy.Execute(request);
                System.Diagnostics.Debug.Write(string.Format("Updated : {0}", 
                  request.Target.LogicalName), EVENT_CATEGORY);
            }
            else // If the record is not found, then do a create.
            {
                System.Diagnostics.Debug.Write(string.Format(
                  "Create initiated, as record does NOT exist : {0}", 
                  artifact.Name), EVENT_CATEGORY);
                        
                List<Zenbus.IT.ControlCenter.CoreData.BTS.Orchestration> list = 
                  new List<CoreData.BTS.Orchestration>();
                list.Add(artifact);

                this.Create(list);
            }
        }
        catch (FaultException<OrganizationServiceFault> fault)
        {
            if (fault.Detail.ErrorCode == -2147220685)
            {
                System.Diagnostics.Debug.Write("Duplicate detected. Reason: " + 
                                               fault.Reason.ToString(), EVENT_CATEGORY);
            }
            else
            {
                throw;
            }
        }
    }

    System.Diagnostics.Debug.Write("Update() complete.", EVENT_CATEGORY);
}

How to quickly create an OptionSet in CRM?

This code snippet helps you to populate an OptionSet in CRM.

C#
private static OptionSetValue CreateOptionSet(int optionSetValue)
{
    OptionSetValue optionSetInstance = new OptionSetValue();
    optionSetInstance.Value = optionSetValue;
    return optionSetInstance;
}

CreateOptionSet() usage, while creating an Entity:

C#
entityInstance.Attributes["zen_direction"] = CreateOptionSet(100000001);

Source code references

After installing the CRM SDK, you might also want to check out the samplecode/cs/helpercode directory for additional source code.

Takeaways

It is recommended that you build a C# library to handle most of the scenarios in a CRM integration, this shall help you to code quickly.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect AT&T Wi-Fi Services
United States United States
Naveen has done his Masters (M.S.) in Computer science, has started his career programming the mainframes and now has more than a decade of programming, development and design experience. Naveen has a sharp eye and keen observation skills. Naveen has worked for several companies and strived hard to build large scale business applications and bringing better solutions to the table.
Quite recently Naveen has built a fairly complex integration platform for a large bank. His hobbies include training, mentoring and research. Naveen spends his free time visiting National Parks nationwide.

Naveen has developed the BizTalk Control Center (BCC)
http://biztalkcontrolcenter.codeplex.com

Comments and Discussions

 
QuestionHow to do the same using Javascript / Typescript? Pin
Saidevm12-Nov-14 5:16
Saidevm12-Nov-14 5:16 
GeneralMy vote of 5 Pin
Global Analyser5-Jun-13 22:11
Global Analyser5-Jun-13 22:11 
wow
i think u need review all my knowledge
tnx
GeneralMy vote of 5 Pin
caichangqi13-Mar-13 15:46
caichangqi13-Mar-13 15:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.