Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

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

0.00/5 (No votes)
5 Jun 2013 1  
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.

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.

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.

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.

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.

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.

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.

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.

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

CreateOptionSet() usage, while creating an Entity:

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here