Microsoft Dynamics CRM 2011

Microsoft Dynamics CRM 2011
Showing posts with label CRM 2011 SOAP Services. Show all posts
Showing posts with label CRM 2011 SOAP Services. Show all posts

Saturday, June 9, 2018

CRM RetrieveMultiple QueryExpression to retrieve the top one last created record

In this article we see Step by step How to write a C# query Microsoft Dynamics CRM QueryExpression  to retrieve the top one last created record/modified record , in both CRM 2011 , CRM 2013 ,CRM 2015 and Microsoft Dynamics 365 .
We'll use the IOrganizationService RetrieveMultiple method with a FilterExpression and a ConditionExpression, to get only one record: the latest one created . We also check an attribute for null values .
Usually this C# code will be run from a Dynamics CRM Plugin.
Download the C# code from the following GitHub repository:


We'll see here in only 10 minutes how to write the CRM query , which will be shown this way , for example :
CRM RetrieveMultiple QueryExpression to retrieve the top one last created record



CRM RetrieveMultiple QueryExpression to retrieve the top one last created record/last modified record


First , you need to set which columns to retrieve. It is strongly recommended that you do not select all columns in an of the Microsoft Dynamics CRM SDK entity :
CRM RetrieveMultiple QueryExpression to retrieve the top one last created record



Next, we create the QueryExpression that will hold the query to be send to the OrganizationService , as follows :
CRM RetrieveMultiple QueryExpression to retrieve the top one last created record


There, we add an OrderExpression to sort the records acording to its "createdon" or "modifiedon" attribute.


Then, we cut the results to just the first result and circumscribe them to the first page:

CRM RetrieveMultiple QueryExpression to retrieve the top one last created record



Then, we can check some determined attribute to contain a value - with the not null ConditionOperator:

CRM RetrieveMultiple QueryExpression to retrieve the top one last created record



And include all conditions in a FilterExpression, into the Criteria:
CRM RetrieveMultiple QueryExpression to retrieve the top one last created record





The complete query will look something like this (this code has been tested , and works very well) :

CRM RetrieveMultiple QueryExpression to retrieve the top one last created record





The steps are as follows:
0) Set which columns to retrieve.
1) Create the QueryExpression
2) Add an OrderExpression
3) Check some determined attribute to contain a value using a ConditionOperator (optional)
4) Include all conditions inside  the Criteria as a FilterExpression
5) Send a RetrieveMultiple with the QueryExpression


Happy CRM.....

      by Carmel Schvartzman


כתב: כרמל שוורצמן

Tuesday, November 19, 2013

How to consume the CRM 2011 Organization (SOAP) WCF Services programmatically

by Carmel Schvartzman

  1. In this walkthrough we will learn  Step By Step  How to call the CRM 2011 Organization (SOAP) Services  in Dynamics CRM 2011. We'll call the CRM 2011 WCF Web Service and perform CRUD operations using Indexing on the generic Entity class.  We'll consume the CRM 2011 Organization (SOAP) services from a class which can also be used by a console application, or a Windows Service, or a Windows Form application.
    We'll not be using the Microsoft CRM SDK 2011; instead we'll reach directly the CRM 2011 WCF SOAP endpoint to perform the CRUD operations. That means, we will not need an early binding proxy with the classes and methods available at the CRM organization. Instead, we will use Late Binding in our calls to the CRM WCF service.
  2. By enabling Indexing we mean that we could access an Entity property getting/setting its value, by using an " entity["field_name"]  "  sintax, while reaching Crm2011 from a WIN app via its Organization Web Service. Therefore, a code like the following....:
    How to consume the CRM 2011 Organization (SOAP) WCF Services programatically

    ... will allows us to create a new Contact, for example:
  3. In order to create a client for the CRM2011 Organization Service, we'll create a .dll which will send requests to the CRM2011 Organization SOAP Web Service Endpoint. Then, we'll create a WIN project to use that assembly and fetch the CRM data, and also create new entities.
  4. So let's create a new Class Project in Visual Studio 2010 or 2008, selecting the target framework to be version 3.5:
  5. Next, add the CRM 2011 Web Service reference to the project:
  6. Remember that we'll be using the Organization CRM SOAP Web Service, so type the address:
  7. After adding the Web Service reference, rename the Class :
  8. Type an static method returning an IOrganizationService object. This method will receive as parameters the host, the CRM organization and user logon data:
  9. Now add the following security code for reaching the CRM Web Service :





    SymmetricSecurityBindingElement security = new SymmetricSecurityBindingElement();
    security.ProtectionTokenParameters = new SspiSecurityTokenParameters();
    HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
    httpTransport.MaxReceivedMessageSize = Int32.MaxValue ;
    CustomBinding binding = new CustomBinding();
    binding.Elements.Add(security);
    TextMessageEncodingBindingElement encoding =
    new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8);
    binding.Elements.Add(encoding);
    binding.Elements.Add(httpTransport);

     
  10. Now add the WCF Endpoint code:



    EndpointAddress endpoint =
    new EndpointAddress(new Uri(string.Format("{0}/{1}/XRMServices/2011/Organization.svc", host, organization)),
    EndpointIdentity.CreateUpnIdentity(string.Format("{0}@{1}", user, "")), new AddressHeader[] { });



    The "host" variable holds the name of your CRM server , and the "organization" variable is the name of your organization.
     
  11. And finally add the code to create the Client:





    OrganizationServiceClient client = new OrganizationServiceClient(binding, endpoint);
    client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(user, password, "");

     
  12. Check that we have all the "usings" we need:
  13. Also, check whether all the references are listed:
  14. Now, in order to perform the testings on our class, create a new console Project , which will call our CRM assembly:
  15. Add the following references:
  16. First, add the Runtime.Serialization assembly:
  17. Second, add our class assembly:
  18. Now, code a call to the IOrganizationService:
  19. Add the corresponding using:
  20. ... and type the relevant logon data, for security reasons:
  21. Next, select some columns that you want to retrieve, and instantiate the entity object:
  22. Check in the QuickWatch window that you get an account with the required attributes:


  23. Now, try to use the  "account["field_name"]" sintax, that means to use Indexing on the Entity class:
  24. It seems that,  if we want to use the "account["field_name"]" sintax, we'll be confronted with an error:
  25. Same thing will happen if we try to create a new record, let's say a new Contact:
  26. According to the error message, Indexing cannot be applied to an Entity.
  27. To solve the problem, let's add Indexing support to the Entity class. We'll extend the Entity class by using two collections: the FormattedValueCollection and the RelatedEntityCollection:
  28. Lookup also the RelatedEntityCollection documentation on MSDN:
  29. Both collections are defined as OptionalFieldAttribute on the Serialization assembly, meaning that the formatters will not require such fields while serializing the Entity class:
  30. Take a look at the FormattedValuesField in the "References" .cs file on your project:


    As you can see, the Entity class is partial, can be extended, and the FormattedValuesField is an optional collection.
  31. Therefore, the first thing we'll do is instantiate those two fields in the partial Entity constructor:
  32. Next, we'll add the Indexing feature to allow a "entity["field_name"] " sintax:
  33. Then, code the get/set functions of the indexing using the AttributeCollection class:
  34. Press "F12" on the AttributeCollection to see that object:


    It's a generic List<> of  KeyValuePair<string,object>, therefore let's code according to that.
  35. Create a static class to hold the Extensions we need to interact with that List<>. Inside the static class, type the get - set extension methods for that List<>:
  36. There are two simple cases that can happen while getting-setting a value from-to a collection. Let's code against them first. In the case of the "get" extension method, prepare to throw an exception if the key does not exists:
  37. In the case of the "set" extension method, the value does not exists in the collection, so just add it to the List.
  38. Next, the two important cases are when the value is in the collection , and we need to know the index it is in, in order to fetch it....:


    ...and when the value is in the collection, and we must override it with the new value. In both cases we'll use a method to get the index of the cell holding the value: GetIndex<K,V>(IList<> col,K key, out i).
  39. Create the  GetIndex<K,V>(IList<> col,K key, out i) method:
  40. Code the basic case in which the collection is null:
  41. .. Next add the code for the Index search:
  42. We're done. Compile and run the WIN Startup Project which uses the assembly:

    We can see that the Indexing is now working, and we can fetch the Account name, and also create a new Contact record.
  43. Finally, let's check our CRM 2011 Workplace to see the new Contact added:




    That's all...Enjoy Dynamics CRM


    כתב: כרמל שוורצמן