Microsoft Dynamics CRM 2011

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

Friday, December 20, 2019

Deep Insert Request for Account Entity using AJAX on Dynamics 365


The following request body posted to the Account entity set will create a total of four new entities in the context of creating an account.
· A contact is created because it is defined as an object property of the single-valued navigation property primarycontactid.
· An opportunity is created because it is defined as an object within an array that is set to the value of a collection-valued navigation property opportunity_customer_accounts.
· A task is created because it is defined an object within an array that is set to the value of a collection-valued navigation property Opportunity_Tasks.The following is the source I used for this:

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/create-entity-web-api#bkmk_CreateRelated


var fnDeepInsert = () => {

    let entityName = "accounts";
    let clientURL = parent.Xrm.Page.context.getClientUrl();
    let req = new XMLHttpRequest();

    req.open("POST", encodeURI(clientURL + "/api/data/v9.1/" + entityName, true));
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");

    req.onreadystatechange = function () {
        if (this.readyState == 4  ) {
            req.onreadystatechange = null;
            if (this.status == 204) {
                alert("No Content = Four Entities created using DEEP INSERT");
            }
            else {
                let error = JSON.parse(this.response).error;
                alert(error.message);
            }
        }
    };

    req.send(JSON.stringify(
        {
            name: "Account",
            primarycontactid:
            {
                firstname: "Bender",
                lastname: "Rodriguez"
            },
            opportunity_customer_accounts:
            [
             {
                 name: "Opportunity for Bender",
                 Opportunity_Tasks:
                 [
                  { subject: "Task related to Bender" }
                 ]
             }
            ]
        }));
}






Friday, December 13, 2019

Dynamics 365 - How to retrieve METADATA for an Entity using a OData REST GET request

In this article we describe  How to retrieve METADATA for an Entity using a OData REST GET request using Web API and Javascript  .



How to retrieve METADATA for an Entity using a OData REST GET request using Web API and Javascript 


Send to the Dynamics webservice the following HTTP request :

http://DOMAIN/ORGANIZATION/api/data/v8.2/EntityDefinitions(LogicalName='phonecall')?$select=LogicalName&$expand=Attributes($select=LogicalName)










That's all...
In this article we've seen  How to retrieve METADATA for an Entity using a OData REST GET request using Web API and Javascript .
Enjoy Microsoft Dynamics 365 CRM!

by Carmel Schvartzman

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

Tuesday, April 16, 2019

Dynamics 365 - How to Update Entity attributes using Web API and Javascript in 5 minutes

In this article we describe Step by step How to Update Entity attributes using Web API and Javascript in 5 minutes.
In this example, we send an HTTP PATCH request to the Dynamics 365 Web Api, in order to update several attributes, and also a MANY-TO-ONE relationship reference between Phonecall and Contact.
We use the HTTP PATCH verb since we are updating more than ONE attribute. Elsewhere, we should use the HTTP PUT OData REST method.


How to Update Entity attributes using Web API and Javascript in 5 minutes  



The following code sends an HTTP PATCH request to the Dynamics 365 Web Api, in order to update several attributes, and also a MANY-TO-ONE relationship reference between Phonecall and Contact:



 var fnPATCHEntity = (newEntityId) => {
            //debugger;
            var entity = {};
            entity.phonenumber = document.getElementById("Phone").value;            
            entity.description = document.getElementById("Description").value;
            entity["regardingobjectid_contact@odata.bind"] = "/contacts(" + newEntityId + ")";
            let id = parent.Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');


            $.ajax({
                type: "PATCH",
                contentType: "application/json; charset=utf-8",
                datatype: "json",
                url: Xrm.Page.context.getClientUrl() + "/api/data/v8.2/phonecalls(" + id + ")",
                data: JSON.stringify(entity),
                beforeSend: function (XMLHttpRequest) {
                    XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
                    XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
                    XMLHttpRequest.setRequestHeader("Accept", "application/json");
                },
                async: true,
                success: function (data, textStatus, xhr) {
                    Xrm.Utility.alertDialog('Phonecall Updated with MANY-TO-ONE relationship!!');
                },
                error: function (xhr, textStatus, errorThrown) {
                    Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
                }
            });

        }




That's all...
In this article we've seen Step by step How to Update Entity attributes using Web API and Javascript in 5 minutes.
Enjoy Microsoft Dynamics 365 CRM!

by Carmel Schvartzman

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

Dynamics 365 - How to Create a MANY-TO-ONE related Entity record using Web API and Javascript in 5 minutes

In this article we describe Step by step How to Create a MANY-TO-ONE related Entity record using Web API and Javascript in 5 minutes.
This Web Resource uses Bootstrap and JQuery , to issue HTTP POST and HTTP PATCH requests to a Dynamics 365 Organization, using the Web Api, in order to Create a new Contact record, related to a current Phonecall. 

The UI looks like this :










How to Create a MANY-TO-ONE related Entity record using Web API and Javascript in 5 minutes  



There will be 2 functions, one for creating a new Contact record with HTTP POST , like this :





And the second function, in order to UPDATE the current Phonecall record, setting its Contact reference regardingobjectid_contact to the guid of the newly created Contact :






The following is the whole Web Resource, to be copied as a building block to your Dynamics Organization :


<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <script>

        // Create a MANY-TO-ONE relationship :  Créer une relation plusieurs-à-un phonecalls-contact :
        var fnPATCHRelatedEntity = (newEntityId) => {
            //debugger;
            var entity = {};
            entity["regardingobjectid_contact@odata.bind"] = "/contacts(" + newEntityId + ")";
            let id = parent.Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
            // In case you want to modify another attribute :  Au cas ou tu veux modifier un autre attribut :
            // entity.phonenumber = "0546589251";

            parent.$.ajax({     //  We can use HTTP PUT whenever we need to modify only ONE attribute
                type: "PATCH",  //  on peut utiliser le verbe HTTP PUT , dans le cas de modification de 1 seul attribut
                contentType: "application/json; charset=utf-8",
                datatype: "json",
                url: parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/phonecalls(" + id + ")",
                data: JSON.stringify(entity),
                beforeSend: function (XMLHttpRequest) {
                    XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
                    XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
                    XMLHttpRequest.setRequestHeader("Accept", "application/json");
                },
                async: true,
                success: function (data, textStatus, xhr) {
                    parent.Xrm.Utility.alertDialog('Phonecall Updated with MANY-TO-ONE relationship!!');
                },
                error: function (xhr, textStatus, errorThrown) {
                    parent.Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
                }
            });

        }

        var fnCreateContact = () => {
            //debugger;
            var entity = {};
            entity.address1_telephone1 = document.getElementById("Phone").value;
            entity.emailaddress1 = document.getElementById("Email").value;
            entity.firstname = document.getElementById("FirstName").value;
            entity.lastname = document.getElementById("LastName").value;

            parent.$.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                datatype: "json",
                url: parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contacts",
                data: JSON.stringify(entity),
                beforeSend: function (XMLHttpRequest) {
                    XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
                    XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
                    XMLHttpRequest.setRequestHeader("Accept", "application/json");
                },
                async: true,
                success: function (data, textStatus, xhr) {
                    let uri = xhr.getResponseHeader("OData-EntityId");
                    let regExp = /\(([^)]+)\)/;
                    let matches = regExp.exec(uri);
                    let newEntityId = matches[1];
                    if (newEntityId != null) {
                        // Créer une relation plusieurs-à-un phonecalls-contact :
                        fnPATCHRelatedEntity(newEntityId);
                    }


                    document.getElementById('btnCreateContact').classList.add('disabled');
                },
                error: function (xhr, textStatus, errorThrown) {
                    parent.Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
                }
            });
        }


    </script>

</head>
<body style="direction: rtl; overflow-wrap: break-word;">

    <div class="container">
        <div class="jumbotron">
            <h3>Create Contact</h3>
            <p></p><h5>This function creates a new Contact related to the current Phonecall through a One-To-Many relationship</h5><p></p>
            <table style="font:12px;border-spacing:3px;margin:5px;">
                <tbody>
                    <tr>
                        <td>First Name: </td>
                        <td><input type="text" id="FirstName" value="Bender"></td>
                    </tr>
                    <tr>
                        <td>Last Name: </td>
                        <td><input type="text" id="LastName" name="LastName" value="Rodriguez"></td>
                    </tr>
                    <tr><td>Email: </td><td><input type="text" id="Email" value="www.bender.com"></td></tr>
                    <tr>
                        <td>Phone: </td>
                        <td><input type="text" id="Phone" name="Phone" value="123456789"></td>
                    </tr>
                </tbody>
            </table>

            <button id="btnCreateContact" onclick="fnCreateContact()" type="button" class="btn btn-primary">Create Contact</button>

        </div>
    </div>
</body>
</html>










That's all...
In this article we've seen Step by step How to Create a MANY-TO-ONE related Entity record using Web API and Javascript in 5 minutes.
Enjoy Microsoft Dynamics 365 CRM!

by Carmel Schvartzman

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

Dynamics 365 - How to Create a new Entity record using Web API and Javascript in 5 minutes

In this article we describe Step by step  How to Create a new Entity record  using Web API and Javascript in 5 minutes. We'll use the JQuery already loaded by Dynamics 365 on the form.

For this example, we'll create a Contact record, when clicking a button, using a Web Resource locally inside the Form.


How to Create a new Entity record  using Web API and Javascript in 5 minutes



This is the function to Create a Record , using an HTTP POST request: 


var entity = {};
entity.address1_telephone1 = "";
entity.emailaddress1 = "";
entity.lastname = "";

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contacts",
    data: JSON.stringify(entity),
    beforeSend: function(XMLHttpRequest) {
        XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
        XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
        XMLHttpRequest.setRequestHeader("Accept", "application/json");
    },
    async: true,
    success: function(data, textStatus, xhr) {
        var uri = xhr.getResponseHeader("OData-EntityId");
        var regExp = /\(([^)]+)\)/;
        var matches = regExp.exec(uri);
        var newEntityId = matches[1];
    },
    error: function(xhr, textStatus, errorThrown) {
        Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
    }
});



And this is the Web Resource EMBEDDED in the Form (that's why we wrote "parent" before calls to JQuery ) :
1) Open the Form
2) Add > Section > Web Resource
3) Paste inside it the following HTML - JS code:



<html><head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script>

var fnCreateContact = () => {
var entity = {};
entity.address1_telephone1 = "123123123";
entity.emailaddress1 = "www.bender.com";
entity.lastname = "Contact Name";

parent.$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contacts",
    data: JSON.stringify(entity),
    beforeSend: function(XMLHttpRequest) {
        XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
        XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
        XMLHttpRequest.setRequestHeader("Accept", "application/json");
    },
    async: true,
    success: function(data, textStatus, xhr) {
        var uri = xhr.getResponseHeader("OData-EntityId");
        var regExp = /\(([^)]+)\)/;
        var matches = regExp.exec(uri);
        var newEntityId = matches[1];

document.getElementById('btnCreateContact').classList.add('disabled');
    },
    error: function(xhr, textStatus, errorThrown) {
        parent.Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
    }
});
}
</script>
<meta></head><body style="direction: rtl; overflow-wrap: break-word;">

<div class="container">
  <div class="jumbotron">
    <h3>Create Contact</h3>   
    <p>This function creates a new Contact</p>
     <button id="btnCreateContact" onclick="fnCreateContact()" type="button" class="btn btn-primary">Create Contact</button>
  </div>
</div>

</body></html>






That's all...
In this article we've seen Step by step  How to Create a new Entity record  using Web API and Javascript in 5 minutes.
Enjoy Microsoft Dynamics 365 CRM!

by Carmel Schvartzman

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

Step by step How to Install the CRM REST Builder in your Dynamics CRM 365 in 5 minutes

In this article we describe Step by step How to Install the CRM REST Builder in your Dynamics CRM 365 in 5 minutes.
The CRM REST Builder is an open source creation by  Jason Lattimer. It will give you the chance of getting the REST OData code that you need, both using JQuery or XMLHttpRequest, automatically and avoiding to fall on errors. The Builder enables you to perform WEB API OData REST request to create One to Many , Many to One and Many to Many relationships, asynchronously:



How to Install the CRM REST Builder in your Dynamics CRM 365 in 5 minutes

1) Download the REST BUILDER:
Browse to the Jason Lattimer's Github , and download the Builder , according to your Dynamics CRM version: https://github.com/jlattimer/CRMRESTBuilder/releases



2) Import the Managed Solution to your Dynamics 365:
Open your solutions screen, and import the REST Builder solution:



3) Open the REST BUILDER:
After refreshing the Solutions form, you will see a button on the top of the form. Open it to see the Builder:





4) Create your REST request:

Create your request, and copy it to the web resource that will be called from your entity form:








That's all...
In this article we've seen Step by step How to Install the CRM REST Builder in your Dynamics CRM 365 in 5 minutes.
Enjoy Microsoft Dynamics 365 CRM!

by Carmel Schvartzman

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










    Wednesday, April 10, 2019

    Dynamics 365 - How to Retrieve Many-To-One related Entity attributes using Web API and Javascript

    In this article we describe Step by step  How to Retrieve Many-To-One related Entity attributes using Web API and Javascript in 5 minutes. We use the JQuery included in the Dynamics form.
    This is our example :  we want to get attributes from a Contact related to a Phonecall :
    This is a MANY-TO-ONE relationship, therefore :
    Primary Entity = Contact
    Related Entity = Phonecall
    Link Entity = regardingobjectid_phonecall_contact 
     (this logical name can be inferred from the N:1 link as seen in the Customizations : see this snapshot : )





    How to Retrieve Many-To-One related Entity attributes using Web API and Javascript 



    This approach works by creating only one web resource embedded into the Form HTML page of the entity :
    1) Open the Form - Add a new Region
    2) Add a Web Resource to the Region
    3) Click on Create New Web Resource 
    4) Add the following Building Block code to the Web Resource :

    This code:
    - loads Bootstrap
    - uses JQuery form the Parent Form
    - Gets Attributes from both the current Entity (Phonecall) + the related MANY-TO-ONE Entity (Contact) :


    <html><head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <script> 
       
        function fnGetContactDetails() {

          debugger;
          let gPrimaryEntityId = parent.Xrm.Page.data.entity.getId();

          if (gPrimaryEntityId) {

            gPrimaryEntityId = gPrimaryEntityId.replace("{", "").replace("}", "");

            parent.$.ajax({
              type: "GET",
              contentType: "application/json; charset=utf-8",
              datatype: "json",
              url: encodeURI(parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/phonecalls(" + gPrimaryEntityId + ")?$select=activityid,phonenumber&$expand=regardingobjectid_contact_phonecall($select=contactid,fullname,accountrolecode,emailaddress1,telephone1,mobilephone,company)"),
              beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
                XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
                XMLHttpRequest.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
              },
              async: true,
              success: function (data, textStatus, xhr) {
                var result = data;
                var activityid = result["activityid"];
                var phonenumber = result["phonenumber"];
                if (result.hasOwnProperty("regardingobjectid_contact_phonecall")) {
                  var contactid = result["regardingobjectid_contact_phonecall"]["contactid"];
                  var fullname = result["regardingobjectid_contact_phonecall"]["fullname"];
                  let accountrolecode = result["regardingobjectid_contact_phonecall"]["accountrolecode"];
                  let emailaddress1 = result["regardingobjectid_contact_phonecall"]["emailaddress1"];
                  let telephone1 = result["regardingobjectid_contact_phonecall"]["telephone1"];
                  let company = result["regardingobjectid_contact_phonecall"]["company"];
                  let mobilephone = result["regardingobjectid_contact_phonecall"]["mobilephone"];


                  document.getElementById("msg").innerHTML = fullname + "<br>" + // accountrolecode + "<br>" + 
                             emailaddress1 + "<br>" + telephone1 + "<br>" + company + "<br>" + mobilephone;

                document.getElementById("btnGetContact").style.display = "none";
                  // parent.Xrm.Utility.alertDialog(fullname);
                }
              },
              error: function (xhr, textStatus, errorThrown) {
                parent.Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
              }
            });
          }
          else {
            parent.Xrm.Page.ui.alert("No ID for Primary Entity");
          }
        }

    </script>
    <meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta><meta></head><body style="direction: rtl; overflow-wrap: break-word;">


    <div class="container">
      <div class="jumbotron">
        <h3>Contact Details</h3> 
        <button id="btnGetContact" class="btn btn-secondary" onclick="fnGetContactDetails()">Get Contact Details </button> 
        <b><div id="msg"></div></b> 
    </div>

    </div></body></html> 
        
    }







    That's all...
    In this article we've seen Step by step  How to Retrieve Many-To-One related Entity attributes using Web API and Javascript in 5 minutes.
    Enjoy Microsoft Dynamics 365 CRM!

    by Carmel Schvartzman

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

    Wednesday, April 30, 2014

    "The given key was not present in the dictionary" KeyNotFoundException Exception in CRM 2013 Plugin or custom Workflow

    by Carmel Shvartzman

    In this walkthrough we will learn how to take care of the "The given key was not present in the dictionary" - "KeyNotFoundException" error in a Dynamics CRM 2013 (2011) Plug-in or custom Workflow.
    1. A disadvantage of using late-binding when coding a CRM 2013 Plugin is, you shoud be very careful with the attributes names, since there is no compile time checking. 
    2. Specially when you have added a new field to an entity, and you get the "The given key was not present in the dictionary" Exception, you'll be prone to think something is not good with the new field definitions, or worse , the Organization Web Service is not recognizing the new field, or even worse, the Web Service needs to be reset to render the field, or may be you'd be desperately thinking to restart the CRM server to refresh the Web Service.
    3. That's because the error message by CRM may be misleading : you may be expecting that, in case your new field contains a null value, CRM Retrieve() or RetrieveMultiple() or Execute() will locate the field attribute, and fetch a NULL value for it. But CRM wouldn't : it WILL NOT INCLUDE THE KEY IN THE ATTRIBUTE'S DICTIONARY UNLESS IT CONTAINS A VALUE : if your field is not a REQUIRED field, you must code a checking for the presence or absence of the field.
    4. For instance, let's say you've added a new field named "new_test", and inside your Plug In you fetch it as follows:
    5. If the present entity has a NULL value in it , you'll be faced to the "The given Key..." exception:
    6. First think you'll want to check, is whether you requested for the field in the ColumnsSet:
    7. But that's not the problem. You did indeed. However, the "new_test" field attribute IS NOT THERE:

    8. That's because CRM WILL NOT INCLUDE THE KEY IN THE ATTRIBUTE'S DICTIONARY UNLESS IT CONTAINS A VALUE (meaning it was SET or UPDATED).
    9. You MUST perform a check for the field existence, but not a NULL check as this:
    10. You should instead use the ContainsKey(string) method from the Collection, for EVERY NO REQUIRED FIELD on the Entity:



      Hoping it helped you.
      That's all...Enjoy Dynamics CRM


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

    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


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