How to read, create, update and detele objects in Microsoft CRM 2011 on premise via WCF service.

Please note that this code works for ON PREMISE installation of Microsoft CRM 2011.

In this short article I will show you how to access items in CRM 2011 via new built in WCF webservice. You should use WCF when accessing CRM from code and REST when accessing from client browser of Silverlight application.

Of course you can use old style CRM 4.0 like aproach with QueryExpression class and then RetreiveMultiple on IOrganizationService instance, but there is also easier approach.

You will need to download and extract CRM 2011 SDK. Current version is 5.0.3 and you can find it on this link : http://www.microsoft.com/downloads/en/details.aspx?FamilyID=420f0f05-c226-4194-b7e1-f23ceaa83b69

Here are the steps you need to follow :

  1. Create console application (with full .NET fw 4.0, not client profile) (you can ofcourse create WPF, WinForms or ASP.NET app, but for our example we will use console app)
  2. Locate crmsvcutil.exe in sdk\bin folder along with microsoft.crm.sdk.proxy.dll and microsoft.xrm.sdk.dll.
  3. Both assemblies add as reference to the console project and add also .NET FWs System.ServiceModel and System.Runtime.Serialization.
  4. Use crmsvcutil.exe to use early bound aproach, that will generate classes for all entities within CRM 2011 and also your custom ones. (this is essential something like adding webservice reference to webservice in CRM 4.0 times). I used commandline arguments like this :crmsvcutil /url:http://server/organization-name/XRMServices/2011/Organization.svc /o:filename.cs /n:namespace /serviceContextName:context-name. /url – url of services, /o – output file, /n – namespace of generated classes, /serviceContextName is name of service, but when you ommit this switch, no context will be generated at all. Context is used for accessing the entities via WCF.
  5. Add generated .cs file to the project (copy to folder, button Show all files, include in project).
  6. Every generated entity will get it’s dedicated IQueryable collection, so for Account you should query AccountSet, for Annotation you should query AnnotationSet and so on. IQueryable means you can query the store with LINQ expressions.

For access you need only this code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk;
using System.ServiceModel.Description;
using service-namespace;

namespace CrmConsoleApplication2 {
    class Program {
        private static IOrganizationService _service;
        private static OrganizationServiceProxy _serviceProxy;

        static void Main(string[] args) {

            IServiceConfiguration<IOrganizationService> orgConfigInfo =
                ServiceConfigurationFactory.CreateConfiguration<IOrganizationService>(new Uri("http://server/company-name/XRMServices/2011/Organization.svc"));
            var creds = new ClientCredentials();

            using (_serviceProxy = new OrganizationServiceProxy(orgConfigInfo, creds)) {

                // This statement is required to enable early-bound type support.
                _serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());

                _service = (IOrganizationService)_serviceProxy;

                List<Account> acc;
                using (context srv = new context(_service)) {
                    acc = srv.AccountSet.Where(a => a.AccountId != null).ToList();

Account a1 = acc[0]; a1.Name = a1.Name + ” mod mod”; Account a2 = acc[1]; a2.Name = a2.Name + ” mod mod”; srv.UpdateObject(a1);
srv.UpdateObject(a2); srv.SaveChanges();
}
} } } }

And this is what you get @ runtime :

crm2011 accessing accounts wcf service

This indeed is a stupid examle with not checking if there is something at position 0 and 1 but I just wanted to modify something on my account. After modification of account you should call UpdateChanges each object you modified and then to save changes to CRM you should call SaveChanges. All changes will be processed at once.

You should also wrap OrganizationServiceProxy and also contex with using, because they both use IDisposable interface. Calling .ToList() after where on AccountSet will trigger downloading of all entities.

Please be aware, that downloading many objects will create big response from server (just for example 6000+ of our customized account objects created aproximately 180MB response (tracked by fiddler) and my console app expanded to 700MB in RAM when parsing and 500MB after loading all objects).

To create and delete record, you can use snippet like this :

                    Account newaaa = new Account();
                    newaaa.Name = "test acc";

                    srv.AddObject(newaaa);
                    srv.SaveChanges();

                    Account newAcc = srv.AccountSet.Where(a => a.Name == "test acc").FirstOrDefault();
                    srv.DeleteObject(newAcc);
                    srv.SaveChanges();

This will create new account, when invoking SaveChanges after AddObject, object newaaa will be filled with guid of freshly created Account. To delete object you have to “download” new object from service, you can’t use newaaa object, because context isn’t tracking the changes, so it can’t delete the object also.

In case of any questions, just mail me or add comment under the article.

26 thoughts on “How to read, create, update and detele objects in Microsoft CRM 2011 on premise via WCF service.

  1. I’m getting an object not set to an instance of an object error; any ideas?
    Also I’m attempting to use this method to replace the 4.0 method of a file for every entity….
    Any help would be greatly appreciated!!!!!!

  2. Hi,

    I have data in sharepoint 2010. The data contains rating score that I would like to enter the value into CRM 2011 using web service.

    can you give me a snippet code for this?

    if you don’t mind, please email me.

    regards,

  3. If I try to use url in this format “http://server/organization-name/XRMServices/2011/Organization.svc ” get an error that no contract is found when I add a service reference in VS 2010 through the add service reference option. Here http://msdn.microsoft.com/en-us/library/gg594452.aspx, it says different format omitting the organization name. Did you have any problem with crmsvc utility when you created the type classes?

  4. Hi,

    I would like to do some CRUD functionality in a sharepoint 2010 webpart. Like showing a gridview with incidents from the incident case in CRM online 2011. And also add,edit and delete functionality. Do you have some snipped code?

  5. I have error for create account record :
    Value cannot be null.
    Parameter name: service
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.ArgumentNullException: Value cannot be null.
    Parameter name: service

    Source Error:

    Line 164203: /// Constructor.
    Line 164204: ///
    Line 164205: public context(Microsoft.Xrm.Sdk.IOrganizationService service) :
    Line 164206: base(service)
    Line 164207: {

  6. first i set user pass with creds :
    creds.UserName.UserName = “administrator”;
    creds.UserName.Password = “******”;

    and i forget set :

    _service = (IOrganizationService)_serviceProxy;

  7. Hi Dusan

    I need to create web service to create case in crm 2011. Glad if you can send me the snippet code to me for references.

    Thanks

  8. i work with your method and worked in last month but now i working on another crm and i have error :
    1-An error occurred when verifying security for the message.
    i could fix this error by syncing the windows time whith server.but i want use this code for portal and it posible client time not synced .how fix this error?

    2.System.ComponentModel.Win32Exception: The Security Support Provider Interface (SSPI) negotiation failed.
    when i run my web app in visual studio i didn`t have any problem but when deploy my app in iis server i get this error

    1. Hello sir.
      Well since I cant get my hands on your code and environment as such I suppose if the first problem could be fixed with time sync, it has something to do with SSL and requirement you have correct time on your machine. And if I understand correctly this worked on your development machine but you are asking for fix when you don’t have possibility to sync time then I don’t think there is a solution, since the problem lies in checks of whole protocol. Not in your code.

      The second problem might lie in the fact, that if your web app runs in VS then I suppose it runs with your credentials. If you deploy the app then it runs with credentials of IIS and you probably either use impersonation > http://msdn.microsoft.com/en-us/library/aa292118%28v=vs.71%29.aspx

      or grant some rights to account under which IIS runs on the CRM server.

      but please, all this is stuff I guess, not stuff that is guaranteed to work.

      dusan

  9. thanks for replay dusan for first q .really microsoft dont have any solution for syncing time ?so how Integrated portal with crm?

    1. well you could use scripts to sync time like :
      http://social.technet.microsoft.com/Forums/en-US/636865b1-9211-48ca-9430-58f7a4b890ba/update-internet-time-using-batch-script-or-powershell?forum=winserversetup

      http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/05/use-powershell-to-easily-compare-the-time-between-two-computers.aspx

      Second question : I am really not sure what you want/need to do and how you do it. What you might do is (I used this with later versions of Sharepoint for example) – since it was in our infrastructure I was able to create a dedicated user, assign him rights on CRM portal and use impersonation and store name and pwd in web.config. I know its not elegant and safe but it worked at that time. Also you could let IIS pool that you run the web app in let run as this user (so no credentials will be stored anywhere in plaintext – you will be prompted to input them in IIS manager) and then IIS will act as this dedicated user. Since it will run the pool as this selected user.

      I am not working with CRM at this time so I would advice you to search and double check if what I am writing you is still valid solution or not.

      dusan

  10. Hi, i have error in the next line:
    using (context srv = new context(_service))
    Say me this message:
    Error 1 cannot find the type or namespace ‘context’ name (missing a using directive or an assembly reference?)
    Can you help me, please?
    Thanks

  11. Thank you for your help. I will watch this to see if it clears me my trouble on the matter. See you soon and congratulations on your work.
    A greeting

  12. Hello from new, Dusan,
    I have already done the execution of the crmsvcutil and I have all the entities as class nub_encuesta. Now, I do not know is how to make features read, create, and delete a record. I don’t know if you can help me code that you attached to make it work, I have several days with this, since it is my first time of development with a CRM.
    Without more and waiting for news from you in this regard, it receives a warm greeting.
    MiguelVb

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Query;
    using Microsoft.Xrm.Sdk.Client;
    using Microsoft.Xrm.Sdk.Discovery;
    using System.ServiceModel.Description;
    using System.Configuration;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.ServiceModel;
    using System.Diagnostics;
    using System.Xml.Linq;
    using w_ServiceProxy;
    using System.Web;
    using System.Web.UI;
    using System.Runtime.Serialization;
    // These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly
    // found in the SDKbin folder.
    using Microsoft.Xrm.Sdk.Messages;
    using Microsoft.Xrm.Sdk.Metadata;
    // This namespace is found in Microsoft.Crm.Sdk.Proxy.dll assembly
    // found in the SDKbin folder.
    using Microsoft.Crm.Sdk.Messages;

    public partial class _Default : System.Web.UI.Page
    {
    #region Class Level Members
    private int Utc;
    private int Tim;
    private OrganizationServiceProxy _serviceProxy;
    private static IOrganizationService _service;
    #endregion Class Level Members

    protected void Page_Load(object sender, EventArgs e)
    {

    ReadOnlyCollection tzCollection;
    tzCollection = TimeZoneInfo.GetSystemTimeZones();
    foreach (TimeZoneInfo timeZone in tzCollection)
    if (timeZone.DisplayName == “(UTC+01:00) Bruselas, Copenhague, Madrid, París”)
    {
    Utc = Convert.ToInt32(timeZone.Id);
    Tim = Convert.ToInt32(timeZone.Id);
    }
    //**********************************************************************
    //********* Lo Nuevo
    //************************************************************************

    IServiceConfiguration orgConfigInfo =
    ServiceConfigurationFactory.CreateConfiguration(new Uri(“http://93.90.20.147:5555/NubIT/XRMServices/2011/Organization.svc”));

    var creds = new ClientCredentials();
    creds.UserName.UserName = “User”;
    creds.UserName.Password = “Pass”;

    using (_serviceProxy = new OrganizationServiceProxy(orgConfigInfo, creds))
    {

    // This statement is required to enable early-bound type support.
    _serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());

    _service = (IOrganizationService)_serviceProxy;

    List acc;

    {
    nub_encuesta srv = new nub_encuesta();
    {

    Here gives me the error: Error: type ‘Microsoft.Xrm.Sdk.EntityReference’ cannot be converted implicitly in ‘ System.Collections.Generic.List’

    acc = srv.nub_Cliente Where(a => a.AccountId != null).ToList();

    nub_encuesta a1 = acc[0]; a1.nub_name = a1.nub_name + “mod mod”; nub_encuesta a2 = acc[1]; a2.nub_name = a2.nub_name + “mod mod”; srv.UpdateObject(a1);
    srv.UpdateObject(a2); srv.SaveChanges();

    //***************************************************
    //***** CREAR NUEVO REGISTRO
    //****************************************************
    Account newaaa = new Account();
    newaaa.Name = “test acc”;
    srv.AddObject(newaaa);
    srv.SaveChanges();
    //***************************************************
    //***** BORRAR EL REGISTRO LEIDO
    //****************************************************
    Account newAcc = srv.AccountSet.Where(a => a.Name == “test acc”).FirstOrDefault();
    srv.DeleteObject(newAcc);
    srv.SaveChanges();
    }
    }

    }
    }
    //************************************************************************

Leave a Reply

Your email address will not be published. Required fields are marked *