Quantcast
Channel: Microsoft Dynamics 365(CRM) Tips and Tricks » Web API
Viewing all 19 articles
Browse latest View live

Execute fetchxml using Web API in Dynamics CRM 2016

$
0
0

Introduction

Microsoft Dynamics CRM Online 2016 Update and Microsoft Dynamics CRM 2016 (on-premises) introduced new concept called The Web API. It can be used across a wide variety of programming languages, platforms, and devices. The Web API implements the OData (Open Data Protocol), version 4.0, an OASIS standard for building and consuming Restful APIs.

Basically Web API is advanced version of old OData. With the help of Web API you can perform following operation.

  • Create
  • Update
  • Delete
  • Retrieve
  • Retrieve multiple( using odata query and fetch)
  • Execute Web API functions
  • Execute Web API Actions
  • Execute Web API Query Functions

Walkthrough

As earlier version of Odata does not support to execute the fetchxml. To execute fetchxml you have to use SOAP. Now using Web API you can execute the fetchxml.

Below is example that used to execute the fetchxml.

First define your fetchxml and execute using Web API using following code.

If you want retrieve formatted value and data about lookup properties. You have add following line in request header.

xhr.setRequestHeader("Prefer", "odata.include-annotations=*");

Below is the entire code.

// This function is used to retrieve records using fetchxml
            fetch: function (originalFetch, entitySetName, retrieveUsingFetchSuccess, retrieveUsingFetchError) {

                var fetch = null;
                try {
                    //create the fetch
                    fetch = ["<fetch mapping='logical'>", originalFetch, "</fetch>"].join("");
                    //encode the fetchxml
                    fetch = escape(fetch);
                    //create AJAX request
                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        //async: false,
                        url: this.getWebAPIPath() + entitySetName + "?fetchXml=" + fetch,
                        beforeSend: function (xhr) {
                            //Specifying this header ensures that the results will be returned as JSON.
                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; odata.metadata=minimal");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");
                            ////xhr.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
                            xhr.setRequestHeader("Prefer", "odata.include-annotations=*");
                        },
                        success: function (data, textStatus, xhr) {

                            if (data != null) {

                                var entityObj = [];                              
                                var pagingInfo = null;

                                //Check if results contains cookies 
                                //if yes then retrieve next set of records
                                if (data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"] != null) {

                                    //get the pagingcookie
                                    pagingInfo = Inogic.ApiLib.getPagingCookie(data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"]);
                                
                                    //call this function create json object
                                    Inogic.ApiLib.createJsonObject(data, entityObj);

                                    //call this to retrieve more records
                                    Inogic.ApiLib.fetchMore(originalFetch, entitySetName, retrieveUsingFetchSucess, retrieveUsingFetchError,pagingInfo.pageCokies,pagingInfo.pageNumber, entityObj);

                                }
                            }
                                //get the results and create json object
                            else {

                                var entityObj = [];

                                // This function is used to create the json object
                                Inogic.ApiLib.createJsonObject(data, entityObj);

                                //call successcallback
                                retrieveUsingFetchSuccess(entityObj);
                            }
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            retrieveUsingFetchError(Inogic.ApiLib.errorHandler(xhr));
                        }
                    });
                } catch (e) {
                    throw new Error(e);
                }

            };

Web API return 5000 records at time, to retrieve more than 5000 records you have to use paging cookie. To identify more records you can use @Microsoft.Dynamics.CRM.fetchxmlpagingcookie. If query has more records then @Microsoft.Dynamics.CRM.fetchxmlpagingcookie contains value. The format of it given below

var  pagingcookie = data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];
pagingcookie = "<cookie pagenumber="2" pagingcookie="%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b133D006A-E89C-E511-80D8-F0921C194348%257d%2522%2520first%253d%2522%257b46A60D62-BF9C-E511-80DD-6C3BE5A8DACC%257d%2522%2520%252f%253e%253c%252fcookie%253e" istracking="False" />"
You have decode this using "unescape".  
pagingcookie = unescape(pagingcookie;)
When you decode then will looks like below.
pagingcookie  = "<cookie pagenumber="2" pagingcookie="<cookie page="1"><accountid last="{133D006A-E89C-E511-80D8-F0921C194348}" first="{46A60D62-BF9C-E511-80DD-6C3BE5A8DACC}" /></cookie>" istracking="False" />"

From above pagingcookie  you can extract the cookie part & pagenumber and add this to fetchxml  and pass this updated fetchxml to retrieve more records.

When you execute fetch it return data in json format.

To get the value of from result use following code.

  1. String/Number etc

var name = data.value[0].name;

  1. Lookup(Entity Reference)

id: data.value[0]._primarycontactid_value,

name: data.value[0]["_primarycontactid_value@OData.Community.Display.V1.FormattedValue"],

logicalname: data.value[0]["_primarycontactid_value@Microsoft.Dynamics.CRM.lookuplogicalname"],

  1. Option set/Money/DataTime/Boolean

value: data.value[0].revenue

formattedValue :data.value[0]["revenue@OData.Community.Display.V1.FormattedValue"]

Since there were requests to include the code in the API, I have added the code of the functions used here. This is our implementation and not necessarily the only or the best way to have it developed. We have been using XrmServiceToolkit for a while and the code here is a similar implementation for WEB API.

//This function is used to get paging cookies
            getPagingCookie: function (pageCokies) {
                var pagingInfo = {};
                var pageNumber = null;

                try {
                    //get the page cokies
                    pageCokies = unescape(unescape(pageCokies));

                    //get the pageNumber
                    pageNumber = parseInt(pageCokies.substring(pageCokies.indexOf("=") + 1, pageCokies.indexOf("pagingcookie")).replace(/\"/g, '').trim());

                    // this line is used to get the cookie part
                    pageCokies = pageCokies.substring(pageCokies.indexOf("pagingcookie"), (pageCokies.indexOf("/>") + 12));
                    pageCokies = pageCokies.substring(pageCokies.indexOf("=") + 1, pageCokies.length);
                    pageCokies = pageCokies.substring(1, pageCokies.length - 1);

                    //replace special character 
                    pageCokies = pageCokies.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '\'').replace(/\'/g, '&' + 'quot;');

                    //append paging-cookie
                    pageCokies = "paging-cookie ='" + pageCokies + "'";

                    //set the parameter
                    pagingInfo.pageCokies = pageCokies;
                    pagingInfo.pageNumber = pageNumber;

                } catch (e) {
                    throw new Error(e);
                }

                return pagingInfo;
            },

            // This function is used to fetchmore records
            fetchMore: function (originalFetch, entitySetName, retrieveUsingFetchSucess, errorCallback, pageCookies, pageNumber, entityObj) {

                var fetch = null;
                try {

                    //add the pageCookies and pageNumber into FetchXML
                    var fetch = ["<fetch mapping='logical' page='" + pageNumber + "' " + pageCookies + ">", originalFetch, "</fetch>"].join("");

                    //encode the fetchxml
                    fetch = escape(fetch);

                    //Create AJAX request
                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        //async: false,
                        url: this.getWebAPIPath() + entitySetName + "?fetchXml=" + fetch,
                        beforeSend: function (xhr) {
                            //Specifying this header ensures that the results will be returned as JSON.
                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; odata.metadata=minimal");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");
                            ////xhr.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
                            xhr.setRequestHeader("Prefer", "odata.include-annotations=*");
                        },
                        success: function (data, textStatus, xhr) {

                            if (data != null) {

                                var pagingInfo = null;

                                //Check if results contains cookies 
                                //if yes then retrieve next set of records
                                if (data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"] != null) {

                                    //get the pagingcookie
                                    pagingInfo = Inogic.ApiLib.getPagingCookie(data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"]);

                                    //call this function create json object
                                    Inogic.ApiLib.createJsonObject(data, entityObj);

                                    //call this to retrieve more records
                                    Inogic.ApiLib.fetchMore(originalFetch, entitySetName, retrieveUsingFetchSucess, retrieveUsingFetchError, pagingInfo.pageCokies, pagingInfo.pageNumber, entityObj);

                                }
                                else {

                                    // This function is used to create the json object
                                    Inogic.ApiLib.createJsonObject(data, entityObj);

                                    retrieveUsingFetchSucess(entityObj);
                                }
                            }
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            errorCallback(Inogic.ApiLib.errorHandler(xhr));
                        }
                    });
                } catch (e) {
                    throw new Error(e);

                }
            },

Conclusion

In this way, We can use Web API to execute fetchxml instead of SOAP.

Before you move on to the next post, check our Maplytics InfoCenter.


Web API Actions in Dynamics CRM 2016

$
0
0

Taking forward our series on using WEB API in Microsoft Dynamics CRM 2016, we will now touch upon a feature that was not available in ODATA v2 of the earlier versions.

ODATA v2 only provided support for CRUD operations. But Dynamics CRM has some special messages/functions for special operations that are beyond the basic CRUD on an entity. To perform these actions in the earlier versions of Microsoft Dynamics CRM, we had to fall back on SOAP messages.

With Web API, actions are now supported. Action is equivalent to requests that are available in Dynamics CRM.

There are predefined Actions defined in Dynamics CRM 2016 that can be executed using Web API. Following is like where you will find the list of Web API actions. https://msdn.microsoft.com/en-in/library/mt607829.aspx

There are three types of Action as listed below.

  1. Unbound actions: It is not bound to any specific entity. i.e the first parameter to such actions does not include the entity. E.g. WinOpportunity, CancelContract etc
  2. Bound actions: It is bound to specific entity. i.e the first parameter to such actions does not include the entity. e.g. – AddToQueue Action
  3. Custom action: It is custom actions developed by developers using Processes.

We are explaining Web API Action called ConvertSalesOrderToInvoice which corresponds to the organization service ConvertSalesOrderToInvoiceRequest. ConvertSalesOrderToInvoice action is not bound to any entity and does not return a value. ConvertSalesOrderToInvoice Action require following parameters.

SalesOrderId: Guid of the order to convert. (This is compulsory parameter)

ColumnSet: List of attributes to retrieve from the created invoice. (This is compulsory parameter)

Below is the code that are used to execute ConvertSalesOrderToInvoice Action.

//This function is used execute the standard action of webAPI

Here is the main Ajax request that execute the Action.

function executeAction() {

    var saleOrderID = null;

    var columnsSet = null;

    try {      

        //set the param values

        saleOrderID = "D035DD97-3AB5-E511-80E2-6C3BE5A852B0"; 

        columnsSet = new Array("name", "totalamount");      

        //create the action object

        var actionObj = {

            "SalesOrderId": saleOrderID,

            "ColumnSet":

                {

'AllColumns': false,

                    'Columns': columnsSet

                },

        };

        // call this function to execute the action. Please note the () used along with the function name

        Inogic.ApiLib.execute(actionObj, "ConvertSalesOrderToInvoice()", function (data) {

            // open the Created invoice record

            Xrm.Utility.openEntityForm("invoice", data.invoiceid);           

        }, function (error) { throw new Error(error.message);

    } catch (e) {

        alert(e.message);

    }

}

//This function is used to execute the Web API Action

            execute: function (req, reqName, successCallback, errorCallback) {

                //create AJAX request

                $.ajax({

                    type: "POST",

                    contentType: "application/json; charset=utf-8",

                    datatype: "json",

                    url: encodeURI(this.getWebAPIPath() + reqName),

                    data: window.JSON.stringify(req),

                    beforeSend: function (xhr) {

                        //Specifying this header ensures that the results will be returned as JSON.            

                        xhr.setRequestHeader("Accept", "application/json");

                        xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                        xhr.setRequestHeader("OData-MaxVersion", "4.0");

                        xhr.setRequestHeader("OData-Version", "4.0");

                    },

                    success: function (data, textStatus, xhr) {

                        //successCallback function

                        successCallback(data);

                    },

                    error: function (xhr, textStatus, errorThrown) {

                        errorCallback(Inogic.ApiLib.errorHandler(xhr));

                    }});

            },

//This function is used to get the client URL

   getClientUrl: function () {

                //Get the organization URL

                if (typeof GetGlobalContext == "function" &&

                    typeof GetGlobalContext().getClientUrl == "function") {

                    return GetGlobalContext().getClientUrl();

                }               

            }

Similar to this you can execute any Web API actions that are listed and your custom action that you developed.

Conclusion:

Web API can be used for executing messages other than CRUD as well.

Everything in Maplytics – Dynamics CRM and Bing Maps integration is now a search away at our Maplytics InfoCentre.

Web API functions in Dynamics CRM 2016

$
0
0

The Web API which is introduced in Microsoft Dynamics CRM 2016 enhances the experience while developing through different programming languages, devices and platforms. It implements the OData, version 4.0, an OASIS standard which is used to build as well as to consume RESTful APIs over rich data sources.

There are predefined functions introduced in the Web API which when executed help you to retrieve data. They may have parameters and they may return values. Functions may be bound to a specific entity. You will find the list of Web API functions on the web page: https://msdn.microsoft.com/en-us/library/mt607866.aspx.

Let’s take an example of RetrieveVersion function

The RetrieveVersion function is used to get the version number of Microsoft Dynamics CRM Server. It is similar to the RetrieveVersionRequest which is used to get the version number through organization services.

The function is not bound to any entity types and does not require any parameters.

Here is the code for executing the standard functions of the WebAPI.

//This function is used execute the standard functions of webAPI

function exeFunction() {
    try {
        Inogic.ApiLib.executeFunction("RetrieveVersion()", exeFunctionSucess, function(error){throw new Error(error.message)};

    } catch (e) {
        showMessage(e.message);
    }
}

//success call back
function exeFunctionSucess(data) {
    try {

        var versionNumber = data;
    }
    catch (e) {
        showMessage(e.message);
    }
}

Here is the main code for executing the functions and fetching the results.

// This function is used to execute the function and get the results
 
            executeFunction: function (funName, successCallback, errorCallback) {

                //create the AJAX request
                $.ajax({
                    type: "GET",
                    contentType: "application/json; charset=utf-8",
                    datatype: "json",                  
                    url: encodeURI(this.getWebAPIPath() + funName),                   
                    beforeSend: function (xhr) {
                        
// This header ensures that the results will be returned as JSON.   
          
                        xhr.setRequestHeader("Accept", "application/json");                    
                     
//xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                        xhr.setRequestHeader("OData-MaxVersion", "4.0");
                        xhr.setRequestHeader("OData-Version", "4.0");
                    },
                    success: function (data, textStatus, xhr) {

                        //successCallback function - Here you get the version number.

                        successCallback(data.Version);
                    },
                    error: function (xhr, textStatus, errorThrown) {
                        errorCallback(Inogic.ApiLib.errorHandler(xhr));
                    }
                });

            }

Web API Query Functions:

Query functions are those which are used to add a filter criteria in Odata query. These functions accept parameters and return a Boolean value. It serves to be an additional filter applied on Odata query.

You would find predefined query functions of Web API in the following link. https://msdn.microsoft.com/en-us/library/mt607843.aspx

Let us consider ThisYear Function. It is used to retrieve data within the current year. It accepts parameter as property name (date attribute name) and returns data within this year.

Note: This function only accepts Date Datatype as a parameter. If you pass a parameter other than the date, then it throws an error.

// This function is used to execute the query function 

function executeQueryFunction() {

    var query = null;

    try {

        // create the query

        query = "?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue";

        // add the query function
 
        query += "&$filter=Microsoft.Dynamics.CRM.ThisYear(PropertyName='modifiedon')";

        //query += "&$filter=Microsoft.Dynamics.CRM.Today(PropertyName='modifiedon')";

        //call this function to execute the query function
        Inogic.ApiLib.executeQueryFunction("accounts", query, executeQueryFunctionSuccess, executeQueryFunctionError, executeQueryFunctionError, false);

    } catch (e) {
        showMessage(e.message);
    }
}

//success call back

function executeQueryFunctionSuccess(data) {
    try {

        //This function is used to process return data

        processData(data);

        HideBusyIndicator();
    }
    catch (e) {
        showMessage(e.message);
    }
}

This is the main Ajax call function.

// This function is used to retrieve records using WebAPI query function

            executeQueryFunction: function (entitySetName, query, successCallback, errorCallback, onComplete) {

                try {
                
                    //create AJAX request

                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        url: encodeURI(oDataUrl),
                        beforeSend: function (xhr) {
                           
//This header ensures that the results will be returned as JSON. 

                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");                          
                            xhr.setRequestHeader("Prefer", "odata.include-annotations=*");

                        },
                        success: function (data, textStatus, xhr) {
                            if (data != null) {
                                successCallback(data.value);                              
                            }
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            errorCallback(xhr.statusText);
                        }
                    });
                } catch (e) {
                    throw new Error(e);
                }

            },

When you execute the above query then it will return all Accounts which are modified during a particular year.

Before moving on to the next post, you may like to read about Dynamics CRM and Bing Maps integration.

Set Values of all Data Types using Web API in Dynamics CRM

$
0
0

In CRM 2016, Microsoft Introduced a new concept called “Web API” (OData v4) to perform CRUD operations as well as other special messages supported in Dynamics CRM. Stepping towards the new enhancement OData v2 is deprecated from the CRM 2016.

Though WEB API too requires the object to be sent in JSON form, it differs a little in the way the values for fields that support complex data type are set. The aim of this blog was to take up most of the common data types used and provide a sample code around how the values need to be set of each of these

Sample code to create an Account Entity Record with all Data Types

///----------- Create with all Data Type (Account) --------
function createAccountWithAllDT() {
    try {
        //declare variables
        var uri = null;
        var stringJSONAcc = null;
        var entityIdWithLink = null;
        var getEntityId = null;

        //create JSON object 
        var JSONAcc = {};

        //set fields using JSON object
        //Single line of text
        JSONAcc.name = "CompanyName Pvt. Ltd."; //Account Name
        
        //Option Set
        JSONAcc.accountcategorycode = "2" //Category : 1--> Preferred Customer, 2--> Standard

        //Two Options
        JSONAcc.donotsendmm = false;//Marketing Materials : 0-->False/Send, 1-->True/Do Not Send
        //Whole Number
        JSONAcc.numberofemployees = 151; //Number of Employees

        //Decimal Number
        JSONAcc.new_decimalnumber = 345.12; //Decimal Number (Custom Field) 

        //Lookup
        JSONAcc["transactioncurrencyid@odata.bind"] = "/transactioncurrencies(4e950855-9eb3-e511-80de-6c3be5a8ad10)"; //Currency

        JSONAcc["primarycontactid@odata.bind"] = "/contacts(DFE54660-37CD-E511-80DE-6C3BE5A831DC)" //Primary Contact

        //Currency
        JSONAcc.creditlimit = 15000; //Currency Limit

        //Date 
        JSONAcc.new_dateonly = new Date();//Date Only (Custom Field)

        //convert JSON object to string
        stringJSONAcc = JSON.stringify(JSONAcc);

        //url for ajax request to create account
        uri = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/accounts";

        //ajax request to create account
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: uri,
            data: stringJSONAcc,
            beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
                XMLHttpRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                XMLHttpRequest.setRequestHeader("Prefer", "odata.include-annotations=*");
            },
            //Success Callback Function
            success: function (data, textStatus, XMLHttpRequest) {
                //get Response from Created Record
                entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record  
                getEntityId = entityIdWithLink.split(/[()]/);
                getEntityId = getEntityId[1];

                //Display Enttity ID of Created Record
                Xrm.Utility.alertDialog("Entity ID : " + getEntityId);
            },
            //Error Callback Function
            error: function () {
                Xrm.Utility.alertDialog("Something Wrong in Script POST...:(");
            }
        });
    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}

Sample code to create an Activity & set Activity Party

///------------ Create Phone Call Activity ----------

function createPhoneCall() {
    try {
        //declare variables
        var phonecallId = null;
        var stringJSONPhone = null;
        var urlPhone = null;

        //create activity party collection
        var parties = [];

        //create JSON object 
        var JSONPhone = {};

        //set fields using JSON object
        //Single line of text
        JSONPhone["subject"] = "Test Phone Call"; //Subject

        //Single line of text & format of phone 
        JSONPhone["phonenumber"] = "9876543210"; //Phone Number

        //Multiple Line of Text
        JSONPhone["description"] = "Phone Call Activity for Testing Purpose only...!"; //Description

        //Date and Time
        JSONPhone["scheduledend"] = new Date(); //Due

        //Lookup
        JSONPhone["regardingobjectid_account@odata.bind"] = "/accounts(B386D403-F7AD-E511-80DC-A45D36FC4F90)"; //Regarding is an account

        //ActivityParty (From)
        var sender = {};
        sender["partyid_systemuser@odata.bind"] = "/systemusers(D949B11D-9240-4037-8379-F31C7A36680E)";
        sender["participationtypemask"] = 1; //From

        //ActivityParty (To)
        var receiver1 = {};
        receiver1["partyid_account@odata.bind"] = "/accounts(B386D403-F7AD-E511-80DC-A45D36FC4F90)";
        receiver1["participationtypemask"] = 2; //To
        //receiver["addressused"] = "roohi@dyn20161.onmicrosoft.com";

        var receiver2 = {};
        receiver2["partyid_contact@odata.bind"] = "/contacts(DFE54660-37CD-E511-80DE-6C3BE5A831DC)";
        receiver2["participationtypemask"] = 2; //To

        var receiver3 = {};
        receiver3["partyid_lead@odata.bind"] = "/leads(ED81F0D9-37CD-E511-80DE-6C3BE5A831DC)";
        receiver3["participationtypemask"] = 2; //To

        //add this to collection
        parties.push(sender);
        parties.push(receiver1);
        parties.push(receiver2);
        parties.push(receiver3);

        //pass parties[] to phonecall_activity_parties
        JSONPhone["phonecall_activity_parties"] = parties;

        //Whole Number
        JSONPhone["actualdurationminutes"] = 25; //Duration

        //Two Options
        JSONPhone["directioncode"] = true;//Direction : 0-->False/Incomming, 1-->True/Outgoing

        //convert JSON object to string
        stringJSONPhone = JSON.stringify(JSONPhone);

        //url for ajax request to create phonecall activity
        urlPhone = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/phonecalls";

        //ajax request to create phonecall activity
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            url: urlPhone,
            data: stringJSONPhone,
            beforeSend: function (CreatePhoneCallActivityRequest) {
                CreatePhoneCallActivityRequest.setRequestHeader("Accept", "application/json");
                CreatePhoneCallActivityRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                CreatePhoneCallActivityRequest.setRequestHeader("Prefer", "odata.include-annotations=*");
                CreatePhoneCallActivityRequest.setRequestHeader("OData-MaxVersion", "4.0");
                CreatePhoneCallActivityRequest.setRequestHeader("OData-Version", "4.0");
            },
            //Success Callback Function
            success: function (data, taxtStatus, getPhoneCallActivityResponse) {
                //get Response from Created Record
                phonecallId = getPhoneCallActivityResponse.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record 
                phonecallId = phonecallId.split(/[()]/);
                phonecallId = phonecallId[1];

                //Display Enttity ID of Created Record
                Xrm.Utility.alertDialog("Entity ID : " + phonecallId);

            },
            //Error Callback Function
            error: function (CreatePhoneCallActivityRequest, textStatus, errorThrown) {
                Xrm.Utility.alertDialog("Something Wrong in Script...:(");
            }
        });
    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}

Conclusion:

Lookup, Regarding and Activity parties being special complex field need to be set by providing a reference to the entity type that you intend to set. The field name also includes a reference to the entity as can be seen in the sample code above. This differs from the way it used to be done earlier where entity type used to be provided as a property of the Lookup object instead of in the field name itself.

Accounting inside your Dynamics CRM..try today. Dynamics CRM and QuickBooks Integration.

Impersonation available using WEB API in Dynamics CRM 2016

$
0
0

Introduction:

Microsoft Dynamics CRM online 2016 update and Dynamics CRM 2016 (on-premises) has introduced a new concept called the Web API. This can be used across a wide variety of programming languages, platforms, and devices. One of the features of Web API is Impersonation.

Back in the days of CRM 4, Impersonation through scripting was supported by including the impersonation details in the header of the SOAP request.

Later this feature was removed and there was no way to impersonate a user through Scripting.

Impersonation is used when you want to execute business logic (code) on behalf of another CRM user. This is necessary because the CRM Web services can be called by various clients and services on behalf of a CRM user. Impersonation involves two different users where User (X) is used for executing the code to perform some tasks on behalf of another user (Y).

Walkthrough of Impersonation through Script

The User account (X) has to be given the prvActOnBehalfOfAnotherUser privilege to perform the task.

In order to impersonate a user through the Web API, you need to add ‘MSCRMCallerID’ key with GUID of the impersonated user. In the below example, a new contact entity is created on behalf of the user with systemuserid B65AB846-7EBE-E511-80DF-00155D06F307.

Here’s the code which helps you to impersonate a user through the Web API.

function impersonateUserReq()
{
    var userID = null;

    try {

        // create the contact object
        var contact = new Object();
        contact.firstname = "FirstName";
        contact.lastname = "LastName";
        contact.accountrolecode = 2;
        contact.creditonhold = false;
        contact["parentcustomerid_account@odata.bind"] = "/accounts(89C202DF-B1AF-E511-80E9-00155D06D000)"

        ///set the impersonateUser userid -  
        userID = "B65AB846-7EBE-E511-80DF-00155D06F307";

        Inogic.ApiLib.impersonateUser("contacts", contact, userID,
           impersonateUserSuccess,
           impersonateUserError);
    } catch (e) {
        showMessage(e.message);
    }
}
      // this Actual ajax request function is used to create the record and impersonate the user
            impersonateUser: function (entitySetName, entity,userId, successCallback, errorCallback) {

                var jsonEntity = null;

                try {

                    //create json object
                    var jsonEntity = window.JSON.stringify(entity);

                    //create AJAX request
                    $.ajax({
                        type: "POST",                      
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        url: encodeURI(this.getWebAPIPath() + entitySetName),
                        data: jsonEntity,
                        beforeSend: function (xhr) {
                            //Specifying this header ensures that the results will be returned as JSON.            
                        
                            xhr.setRequestHeader("MSCRMCallerID", userId);
                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");
                        },
                        success: function (data, textStatus, xhr) {

                            //call successCallback
                            successCallback(xhr.getResponseHeader("OData-EntityId"));
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            errorCallback(Inogic.ApiLib.errorHandler(xhr));
                        }
                    });
                } catch (e) {
                    throw new Error(e);
                }
            },

In the above code, the only addition is the following line of code

   xhr.setRequestHeader("MSCRMCallerID", userId);

Once the callerid is set, the record is created using the privileges that is assigned to the user specified in the callerid rather than the logged in user.

Conclusion:

On a concluding note, impersonation helps to perform operations on behalf of other users if the system account running the code has the necessary privileges.

You may also like to read : Make your Dynamics CRM life easy with Inogic Dynamics CRM Solutions.

Set Values of all Data Types using Web API in Dynamics CRM Through C#

$
0
0

Introduction:

With the release of Microsoft Dynamics CRM 2016, Web API which was introduced offers a development experience across many devices, languages and platforms.

In this blog we will take a look at how to set the all the datatypes in the CRM using C# through a windows application and using Web API.

You may refer this blog for connecting the CRM through the Web API.

Sample code to create an Account Entity Record with all Data Types:

//Initialize the WebAPIHandler class on Load of the Form as seen below:

//Global Variable of Class WebApiHandler
WebApiHandler _webAPIHandler=null;
//Method which Waits for all of the provided Task objects(i.e. Start Method in our case) to complete execution
private void CRUD_Load(object sender, EventArgs e)
{         
  Task.WaitAll(Task.Run(async () => await Start()));
}

private async Task Start()
{
  //Initialize the WebAPIHandler class
 webAPIHandler    = new WebApiHandler();
}

//Button click code which creates the Account record.
private void btnCreate_Click(object sender, EventArgs e)
{
            string recordId = string.Empty;

            //A Json Object used to create account record
            JObject account = null;

            //Request Uri to store the accounts path 
            string requestUri = "api/data/v8.0/accounts";

            try
            {
                //Get the Account Object
                account = CreateAccountRecordObject();

                //WebAPI Handler method call to Create Record
                recordId = _webAPIHandler.CreateRecord(account, requestUri);         
     }
            catch (Exception err)
            {

                throw new Exception(err.Message);
            }

        }

    	 /// <summary>
        /// Create Account Record Object
        /// </summary>
        /// <returns></returns>
        private JObject CreateAccountRecordObject()
        {
            JObject account = null;
            try
            {
                account = new JObject();

                //String Value
                account["name"] = "Sid Test Co";//Account Name

                //Optionset
                account["accountcategorycode"] = "2"; //Category : 1--> Preferred Customer, 2--> Standard

                //Two Options
                account["donotsendmm"] = false; //Marketing Materials : 0-->False/Send, 1-->True/Do Not Send

                //Whole number
                account["numberofemployees"] = 100;//Number of Employees

                //Custom Decimal Field
                account["new_creditrate"] = 2.25;//Decimal Number (Custom Field) 

                //Lookup
                //Setting the Primary Contact
                account["primarycontactid@odata.bind"] = "/contacts(E15C03BA-10EC-E511-80E2-C4346BAD87C8)"; //Primary Contact

                //setting the Transaction Currency
                account["transactioncurrencyid@odata.bind"] = "/transactioncurrencies(63D588A2-10EC-E511-80E2-C4346BAD87C8)"; //Currency

                //Currency/Money Field
                account["creditlimit"] = 1000; //Currency Limit

                //Custom Date Only Field
                account["new_effectivedate"] = DateTime.Now; //Date Only (Custom Field)


               
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }
            return account;
        }

Sample code to create an Activity & set Activity Party:

/// <summary>
        /// To Create the Phone Call Record
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreatePhoneCall_Click(object sender, EventArgs e)
        {
            //Request Uri to store the accounts path 
            string requestUri = "api/data/v8.0/phonecalls";
            string recordId = string.Empty;
            try
            {
                //Create Phone Call Object
                JObject phoneCall = CreatePhoneCall();
                //WebAPI Handler method call to Create Record
                recordId = _webAPIHandler.CreateRecord(phoneCall,requestUri);
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }

        }


        /// <summary>
        /// Create PhoneCall Object
        /// </summary>
        /// <returns></returns>
        private JObject CreatePhoneCall()
        {
            //create activity party collection
            JArray parties = new JArray();

            //create JSON object 
            JObject jsonPhoneCall = new JObject();


            try
            {
                //set fields using JSON object
                //Single line of text
                jsonPhoneCall["subject"] = "Test Phone Call" + DateTime.Now.ToShortDateString(); //Subject

                //Single line of text & format of phone 
                jsonPhoneCall["phonenumber"] = "4565898756"; //Phone Number

                //Multiple Line of Text
                jsonPhoneCall["description"] = "Phone Call Activity for Testing Purpose only...!"; //Description

                //Date and Time
                jsonPhoneCall["scheduledend"] = DateTime.Now; //Due

                //Lookup
                jsonPhoneCall["regardingobjectid_account@odata.bind"] = "/accounts(4B47AA19-88F3-E511-80E6-C4346BACF5C0)"; //Regarding is an account

                //ActivityParty (From)
                JObject sender = new JObject();
                sender["partyid_systemuser@odata.bind"] = "/systemusers(2e68e212-c82d-4bc6-9493-fbd80204a763)";
                sender["participationtypemask"] = 1; //From

                //ActivityParty (To)
                JObject receiver1 = new JObject();
                receiver1["partyid_account@odata.bind"] = "/accounts(4B47AA19-88F3-E511-80E6-C4346BACF5C0)";
                receiver1["participationtypemask"] = 2; //To
                 JObject receiver2 = new JObject();
                receiver2["partyid_systemuser@odata.bind"] = "/systemusers(2e68e212-c82d-4bc6-9493-fbd80204a763)";
                receiver2["participationtypemask"] = 2; //From


                //Add this to collection
                parties.Add(sender);
                parties.Add(receiver1);
                parties.Add(receiver2);


                //pass parties[] to phonecall_activity_parties
                jsonPhoneCall["phonecall_activity_parties"] = parties;

                //Whole Number
                jsonPhoneCall["actualdurationminutes"] = 25; //Duration

                //Two Options
                jsonPhoneCall["directioncode"] = true;//Direction : 0-->False/Incoming, 1-->True/Outgoing 
            }
            catch (Exception error)
            {                
                throw new Exception(error.Message);
            }

            return jsonPhoneCall;

The __webAPIHandler.CreateRecord() method is in WebApiHandler class.

It is as below:

/// <summary>
   /// Method to Return the record ID after creating it in CRM
   /// </summary>
   /// <param name="record"></param>
        /// <param name="requestUrl"></param>
        /// <returns></returns>
        public string CreateRecord(JObject record, string requestUrl)
        {
            string recordId = string.Empty;
            try
            {
                //Create HttpClient object to send and receive Http Requests and Response
                using (HttpClient httpClient = GetHttpClientObject())
                {
                    //Http Request needed to be sent by the HttpClient
                    HttpRequestMessage requestMessage = GetHttpRequestMessage(HttpMethod.Post, requestUrl, record);

                    //Send the HttpRequest
                    Task<HttpResponseMessage> response = httpClient.SendAsync(requestMessage);

                    //Wait till the Response Execution is complete
                    response.Wait();

                    //If the response is Successfully executed then it will return the value true
                    if (response.Result.IsSuccessStatusCode)
                    {
                        _recordUrl = response.Result.Headers.GetValues("OData-EntityId").FirstOrDefault();
                        splitRetrievedData = _recordUrl.Split('[', '(', ')', ']');

                        recordId = splitRetrievedData[1];

                    }
                }
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }

            return recordId;
        }

For the methods GetHttpClientObject(),GetHttpRequestMessage you may refer this blog.

To get the JObject, JArray i.e Json Objects you need to add reference to the Newtonsoft.Json.You may add it through Nuget using this command Install-Package Newtonsoft.Json.

Conclusion:

Hope the above code helps to set all the data types in Dynamics CRM.

Now export your Dynamics CRM Reports to word, excel or pdf in just 1 click with Click2Export

Execute fetchxml using Web API in Dynamics CRM 2016

$
0
0

Introduction

Microsoft Dynamics CRM Online 2016 Update and Microsoft Dynamics CRM 2016 (on-premises) introduced new concept called The Web API. It can be used across a wide variety of programming languages, platforms, and devices. The Web API implements the OData (Open Data Protocol), version 4.0, an OASIS standard for building and consuming Restful APIs.

Basically Web API is advanced version of old OData. With the help of Web API you can perform following operation.

  • Create
  • Update
  • Delete
  • Retrieve
  • Retrieve multiple( using odata query and fetch)
  • Execute Web API functions
  • Execute Web API Actions
  • Execute Web API Query Functions

Walkthrough

As earlier version of Odata does not support to execute the fetchxml. To execute fetchxml you have to use SOAP. Now using Web API you can execute the fetchxml.

Below is example that used to execute the fetchxml.

First define your fetchxml and execute using Web API using following code.

If you want retrieve formatted value and data about lookup properties. You have add following line in request header.

xhr.setRequestHeader("Prefer", "odata.include-annotations=*");

Below is the entire code.

// This function is used to retrieve records using fetchxml
            fetch: function (originalFetch, entitySetName, retrieveUsingFetchSuccess, retrieveUsingFetchError) {

                var fetch = null;
                try {
                    //create the fetch
                    fetch = ["<fetch mapping='logical'>", originalFetch, "</fetch>"].join("");
                    //encode the fetchxml
                    fetch = escape(fetch);
                    //create AJAX request
                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        //async: false,
                        url: this.getWebAPIPath() + entitySetName + "?fetchXml=" + fetch,
                        beforeSend: function (xhr) {
                            //Specifying this header ensures that the results will be returned as JSON.
                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; odata.metadata=minimal");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");
                            ////xhr.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
                            xhr.setRequestHeader("Prefer", "odata.include-annotations=*");
                        },
                        success: function (data, textStatus, xhr) {

                            if (data != null) {

                                var entityObj = [];                              
                                var pagingInfo = null;

                                //Check if results contains cookies 
                                //if yes then retrieve next set of records
                                if (data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"] != null) {

                                    //get the pagingcookie
                                    pagingInfo = Inogic.ApiLib.getPagingCookie(data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"]);
                                
                                    //call this function create json object
                                    Inogic.ApiLib.createJsonObject(data, entityObj);

                                    //call this to retrieve more records
                                    Inogic.ApiLib.fetchMore(originalFetch, entitySetName, retrieveUsingFetchSucess, retrieveUsingFetchError,pagingInfo.pageCokies,pagingInfo.pageNumber, entityObj);

                                }
                            }
                                //get the results and create json object
                            else {

                                var entityObj = [];

                                // This function is used to create the json object
                                Inogic.ApiLib.createJsonObject(data, entityObj);

                                //call successcallback
                                retrieveUsingFetchSuccess(entityObj);
                            }
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            retrieveUsingFetchError(Inogic.ApiLib.errorHandler(xhr));
                        }
                    });
                } catch (e) {
                    throw new Error(e);
                }

            };

Web API return 5000 records at time, to retrieve more than 5000 records you have to use paging cookie. To identify more records you can use @Microsoft.Dynamics.CRM.fetchxmlpagingcookie. If query has more records then @Microsoft.Dynamics.CRM.fetchxmlpagingcookie contains value. The format of it given below

var  pagingcookie = data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];
pagingcookie = "<cookie pagenumber="2" pagingcookie="%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b133D006A-E89C-E511-80D8-F0921C194348%257d%2522%2520first%253d%2522%257b46A60D62-BF9C-E511-80DD-6C3BE5A8DACC%257d%2522%2520%252f%253e%253c%252fcookie%253e" istracking="False" />"
You have decode this using "unescape".  
pagingcookie = unescape(pagingcookie;)
When you decode then will looks like below.
pagingcookie  = "<cookie pagenumber="2" pagingcookie="<cookie page="1"><accountid last="{133D006A-E89C-E511-80D8-F0921C194348}" first="{46A60D62-BF9C-E511-80DD-6C3BE5A8DACC}" /></cookie>" istracking="False" />"

From above pagingcookie  you can extract the cookie part & pagenumber and add this to fetchxml  and pass this updated fetchxml to retrieve more records.

When you execute fetch it return data in json format.

To get the value of from result use following code.

  1. String/Number etc

var name = data.value[0].name;

  1. Lookup(Entity Reference)

id: data.value[0]._primarycontactid_value,

name: data.value[0]["_primarycontactid_value@OData.Community.Display.V1.FormattedValue"],

logicalname: data.value[0]["_primarycontactid_value@Microsoft.Dynamics.CRM.lookuplogicalname"],

  1. Option set/Money/DataTime/Boolean

value: data.value[0].revenue

formattedValue :data.value[0]["revenue@OData.Community.Display.V1.FormattedValue"]

Since there were requests to include the code in the API, I have added the code of the functions used here. This is our implementation and not necessarily the only or the best way to have it developed. We have been using XrmServiceToolkit for a while and the code here is a similar implementation for WEB API.

//This function is used to get paging cookies
            getPagingCookie: function (pageCokies) {
                var pagingInfo = {};
                var pageNumber = null;

                try {
                    //get the page cokies
                    pageCokies = unescape(unescape(pageCokies));

                    //get the pageNumber
                    pageNumber = parseInt(pageCokies.substring(pageCokies.indexOf("=") + 1, pageCokies.indexOf("pagingcookie")).replace(/\"/g, '').trim());

                    // this line is used to get the cookie part
                    pageCokies = pageCokies.substring(pageCokies.indexOf("pagingcookie"), (pageCokies.indexOf("/>") + 12));
                    pageCokies = pageCokies.substring(pageCokies.indexOf("=") + 1, pageCokies.length);
                    pageCokies = pageCokies.substring(1, pageCokies.length - 1);

                    //replace special character 
                    pageCokies = pageCokies.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '\'').replace(/\'/g, '&' + 'quot;');

                    //append paging-cookie
                    pageCokies = "paging-cookie ='" + pageCokies + "'";

                    //set the parameter
                    pagingInfo.pageCokies = pageCokies;
                    pagingInfo.pageNumber = pageNumber;

                } catch (e) {
                    throw new Error(e);
                }

                return pagingInfo;
            },

            // This function is used to fetchmore records
            fetchMore: function (originalFetch, entitySetName, retrieveUsingFetchSucess, errorCallback, pageCookies, pageNumber, entityObj) {

                var fetch = null;
                try {

                    //add the pageCookies and pageNumber into FetchXML
                    var fetch = ["<fetch mapping='logical' page='" + pageNumber + "' " + pageCookies + ">", originalFetch, "</fetch>"].join("");

                    //encode the fetchxml
                    fetch = escape(fetch);

                    //Create AJAX request
                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        //async: false,
                        url: this.getWebAPIPath() + entitySetName + "?fetchXml=" + fetch,
                        beforeSend: function (xhr) {
                            //Specifying this header ensures that the results will be returned as JSON.
                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; odata.metadata=minimal");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");
                            ////xhr.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
                            xhr.setRequestHeader("Prefer", "odata.include-annotations=*");
                        },
                        success: function (data, textStatus, xhr) {

                            if (data != null) {

                                var pagingInfo = null;

                                //Check if results contains cookies 
                                //if yes then retrieve next set of records
                                if (data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"] != null) {

                                    //get the pagingcookie
                                    pagingInfo = Inogic.ApiLib.getPagingCookie(data["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"]);

                                    //call this function create json object
                                    Inogic.ApiLib.createJsonObject(data, entityObj);

                                    //call this to retrieve more records
                                    Inogic.ApiLib.fetchMore(originalFetch, entitySetName, retrieveUsingFetchSucess, retrieveUsingFetchError, pagingInfo.pageCokies, pagingInfo.pageNumber, entityObj);

                                }
                                else {

                                    // This function is used to create the json object
                                    Inogic.ApiLib.createJsonObject(data, entityObj);

                                    retrieveUsingFetchSucess(entityObj);
                                }
                            }
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            errorCallback(Inogic.ApiLib.errorHandler(xhr));
                        }
                    });
                } catch (e) {
                    throw new Error(e);

                }
            },

Conclusion

In this way, We can use Web API to execute fetchxml instead of SOAP.

Before you move on to the next post, check our Maplytics InfoCenter.

Web API Actions in Dynamics CRM 2016

$
0
0

Taking forward our series on using WEB API in Microsoft Dynamics CRM 2016, we will now touch upon a feature that was not available in ODATA v2 of the earlier versions.

ODATA v2 only provided support for CRUD operations. But Dynamics CRM has some special messages/functions for special operations that are beyond the basic CRUD on an entity. To perform these actions in the earlier versions of Microsoft Dynamics CRM, we had to fall back on SOAP messages.

With Web API, actions are now supported. Action is equivalent to requests that are available in Dynamics CRM.

There are predefined Actions defined in Dynamics CRM 2016 that can be executed using Web API. Following is like where you will find the list of Web API actions. https://msdn.microsoft.com/en-in/library/mt607829.aspx

There are three types of Action as listed below.

  1. Unbound actions: It is not bound to any specific entity. i.e the first parameter to such actions does not include the entity. E.g. WinOpportunity, CancelContract etc
  2. Bound actions: It is bound to specific entity. i.e the first parameter to such actions does not include the entity. e.g. – AddToQueue Action
  3. Custom action: It is custom actions developed by developers using Processes.

We are explaining Web API Action called ConvertSalesOrderToInvoice which corresponds to the organization service ConvertSalesOrderToInvoiceRequest. ConvertSalesOrderToInvoice action is not bound to any entity and does not return a value. ConvertSalesOrderToInvoice Action require following parameters.

SalesOrderId: Guid of the order to convert. (This is compulsory parameter)

ColumnSet: List of attributes to retrieve from the created invoice. (This is compulsory parameter)

Below is the code that are used to execute ConvertSalesOrderToInvoice Action.

//This function is used execute the standard action of webAPI

Here is the main Ajax request that execute the Action.

function executeAction() {

    var saleOrderID = null;

    var columnsSet = null;

    try {      

        //set the param values

        saleOrderID = "D035DD97-3AB5-E511-80E2-6C3BE5A852B0"; 

        columnsSet = new Array("name", "totalamount");      

        //create the action object

        var actionObj = {

            "SalesOrderId": saleOrderID,

            "ColumnSet":

                {

'AllColumns': false,

                    'Columns': columnsSet

                },

        };

        // call this function to execute the action. Please note the () used along with the function name

        Inogic.ApiLib.execute(actionObj, "ConvertSalesOrderToInvoice()", function (data) {

            // open the Created invoice record

            Xrm.Utility.openEntityForm("invoice", data.invoiceid);           

        }, function (error) { throw new Error(error.message);

    } catch (e) {

        alert(e.message);

    }

}

//This function is used to execute the Web API Action

            execute: function (req, reqName, successCallback, errorCallback) {

                //create AJAX request

                $.ajax({

                    type: "POST",

                    contentType: "application/json; charset=utf-8",

                    datatype: "json",

                    url: encodeURI(this.getWebAPIPath() + reqName),

                    data: window.JSON.stringify(req),

                    beforeSend: function (xhr) {

                        //Specifying this header ensures that the results will be returned as JSON.            

                        xhr.setRequestHeader("Accept", "application/json");

                        xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                        xhr.setRequestHeader("OData-MaxVersion", "4.0");

                        xhr.setRequestHeader("OData-Version", "4.0");

                    },

                    success: function (data, textStatus, xhr) {

                        //successCallback function

                        successCallback(data);

                    },

                    error: function (xhr, textStatus, errorThrown) {

                        errorCallback(Inogic.ApiLib.errorHandler(xhr));

                    }});

            },

//This function is used to get the client URL

   getClientUrl: function () {

                //Get the organization URL

                if (typeof GetGlobalContext == "function" &&

                    typeof GetGlobalContext().getClientUrl == "function") {

                    return GetGlobalContext().getClientUrl();

                }               

            }

Similar to this you can execute any Web API actions that are listed and your custom action that you developed.

Conclusion:

Web API can be used for executing messages other than CRUD as well.

Everything in Maplytics – Dynamics CRM and Bing Maps integration is now a search away at our Maplytics InfoCentre.


Web API functions in Dynamics CRM 2016

$
0
0

The Web API which is introduced in Microsoft Dynamics CRM 2016 enhances the experience while developing through different programming languages, devices and platforms. It implements the OData, version 4.0, an OASIS standard which is used to build as well as to consume RESTful APIs over rich data sources.

There are predefined functions introduced in the Web API which when executed help you to retrieve data. They may have parameters and they may return values. Functions may be bound to a specific entity. You will find the list of Web API functions on the web page: https://msdn.microsoft.com/en-us/library/mt607866.aspx.

Let’s take an example of RetrieveVersion function

The RetrieveVersion function is used to get the version number of Microsoft Dynamics CRM Server. It is similar to the RetrieveVersionRequest which is used to get the version number through organization services.

The function is not bound to any entity types and does not require any parameters.

Here is the code for executing the standard functions of the WebAPI.

//This function is used execute the standard functions of webAPI

function exeFunction() {
    try {
        Inogic.ApiLib.executeFunction("RetrieveVersion()", exeFunctionSucess, function(error){throw new Error(error.message)};

    } catch (e) {
        showMessage(e.message);
    }
}

//success call back
function exeFunctionSucess(data) {
    try {

        var versionNumber = data;
    }
    catch (e) {
        showMessage(e.message);
    }
}

Here is the main code for executing the functions and fetching the results.

// This function is used to execute the function and get the results
 
            executeFunction: function (funName, successCallback, errorCallback) {

                //create the AJAX request
                $.ajax({
                    type: "GET",
                    contentType: "application/json; charset=utf-8",
                    datatype: "json",                  
                    url: encodeURI(this.getWebAPIPath() + funName),                   
                    beforeSend: function (xhr) {
                        
// This header ensures that the results will be returned as JSON.   
          
                        xhr.setRequestHeader("Accept", "application/json");                    
                     
//xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                        xhr.setRequestHeader("OData-MaxVersion", "4.0");
                        xhr.setRequestHeader("OData-Version", "4.0");
                    },
                    success: function (data, textStatus, xhr) {

                        //successCallback function - Here you get the version number.

                        successCallback(data.Version);
                    },
                    error: function (xhr, textStatus, errorThrown) {
                        errorCallback(Inogic.ApiLib.errorHandler(xhr));
                    }
                });

            }

Web API Query Functions:

Query functions are those which are used to add a filter criteria in Odata query. These functions accept parameters and return a Boolean value. It serves to be an additional filter applied on Odata query.

You would find predefined query functions of Web API in the following link. https://msdn.microsoft.com/en-us/library/mt607843.aspx

Let us consider ThisYear Function. It is used to retrieve data within the current year. It accepts parameter as property name (date attribute name) and returns data within this year.

Note: This function only accepts Date Datatype as a parameter. If you pass a parameter other than the date, then it throws an error.

// This function is used to execute the query function 

function executeQueryFunction() {

    var query = null;

    try {

        // create the query

        query = "?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue";

        // add the query function
 
        query += "&$filter=Microsoft.Dynamics.CRM.ThisYear(PropertyName='modifiedon')";

        //query += "&$filter=Microsoft.Dynamics.CRM.Today(PropertyName='modifiedon')";

        //call this function to execute the query function
        Inogic.ApiLib.executeQueryFunction("accounts", query, executeQueryFunctionSuccess, executeQueryFunctionError, executeQueryFunctionError, false);

    } catch (e) {
        showMessage(e.message);
    }
}

//success call back

function executeQueryFunctionSuccess(data) {
    try {

        //This function is used to process return data

        processData(data);

        HideBusyIndicator();
    }
    catch (e) {
        showMessage(e.message);
    }
}

This is the main Ajax call function.

// This function is used to retrieve records using WebAPI query function

            executeQueryFunction: function (entitySetName, query, successCallback, errorCallback, onComplete) {

                try {
                
                    //create AJAX request

                    $.ajax({
                        type: "GET",
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        url: encodeURI(oDataUrl),
                        beforeSend: function (xhr) {
                           
//This header ensures that the results will be returned as JSON. 

                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");                          
                            xhr.setRequestHeader("Prefer", "odata.include-annotations=*");

                        },
                        success: function (data, textStatus, xhr) {
                            if (data != null) {
                                successCallback(data.value);                              
                            }
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            errorCallback(xhr.statusText);
                        }
                    });
                } catch (e) {
                    throw new Error(e);
                }

            },

When you execute the above query then it will return all Accounts which are modified during a particular year.

Before moving on to the next post, you may like to read about Dynamics CRM and Bing Maps integration.

Set Values of all Data Types using Web API in Dynamics CRM

$
0
0

In CRM 2016, Microsoft Introduced a new concept called “Web API” (OData v4) to perform CRUD operations as well as other special messages supported in Dynamics CRM. Stepping towards the new enhancement OData v2 is deprecated from the CRM 2016.

Though WEB API too requires the object to be sent in JSON form, it differs a little in the way the values for fields that support complex data type are set. The aim of this blog was to take up most of the common data types used and provide a sample code around how the values need to be set of each of these

Sample code to create an Account Entity Record with all Data Types

///----------- Create with all Data Type (Account) --------
function createAccountWithAllDT() {
    try {
        //declare variables
        var uri = null;
        var stringJSONAcc = null;
        var entityIdWithLink = null;
        var getEntityId = null;

        //create JSON object 
        var JSONAcc = {};

        //set fields using JSON object
        //Single line of text
        JSONAcc.name = "CompanyName Pvt. Ltd."; //Account Name
        
        //Option Set
        JSONAcc.accountcategorycode = "2" //Category : 1--> Preferred Customer, 2--> Standard

        //Two Options
        JSONAcc.donotsendmm = false;//Marketing Materials : 0-->False/Send, 1-->True/Do Not Send
        //Whole Number
        JSONAcc.numberofemployees = 151; //Number of Employees

        //Decimal Number
        JSONAcc.new_decimalnumber = 345.12; //Decimal Number (Custom Field) 

        //Lookup
        JSONAcc["transactioncurrencyid@odata.bind"] = "/transactioncurrencies(4e950855-9eb3-e511-80de-6c3be5a8ad10)"; //Currency

        JSONAcc["primarycontactid@odata.bind"] = "/contacts(DFE54660-37CD-E511-80DE-6C3BE5A831DC)" //Primary Contact

        //Currency
        JSONAcc.creditlimit = 15000; //Currency Limit

        //Date 
        JSONAcc.new_dateonly = new Date();//Date Only (Custom Field)

        //convert JSON object to string
        stringJSONAcc = JSON.stringify(JSONAcc);

        //url for ajax request to create account
        uri = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/accounts";

        //ajax request to create account
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: uri,
            data: stringJSONAcc,
            beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
                XMLHttpRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                XMLHttpRequest.setRequestHeader("Prefer", "odata.include-annotations=*");
            },
            //Success Callback Function
            success: function (data, textStatus, XMLHttpRequest) {
                //get Response from Created Record
                entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record  
                getEntityId = entityIdWithLink.split(/[()]/);
                getEntityId = getEntityId[1];

                //Display Enttity ID of Created Record
                Xrm.Utility.alertDialog("Entity ID : " + getEntityId);
            },
            //Error Callback Function
            error: function () {
                Xrm.Utility.alertDialog("Something Wrong in Script POST...:(");
            }
        });
    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}

Sample code to create an Activity & set Activity Party

///------------ Create Phone Call Activity ----------

function createPhoneCall() {
    try {
        //declare variables
        var phonecallId = null;
        var stringJSONPhone = null;
        var urlPhone = null;

        //create activity party collection
        var parties = [];

        //create JSON object 
        var JSONPhone = {};

        //set fields using JSON object
        //Single line of text
        JSONPhone["subject"] = "Test Phone Call"; //Subject

        //Single line of text & format of phone 
        JSONPhone["phonenumber"] = "9876543210"; //Phone Number

        //Multiple Line of Text
        JSONPhone["description"] = "Phone Call Activity for Testing Purpose only...!"; //Description

        //Date and Time
        JSONPhone["scheduledend"] = new Date(); //Due

        //Lookup
        JSONPhone["regardingobjectid_account@odata.bind"] = "/accounts(B386D403-F7AD-E511-80DC-A45D36FC4F90)"; //Regarding is an account

        //ActivityParty (From)
        var sender = {};
        sender["partyid_systemuser@odata.bind"] = "/systemusers(D949B11D-9240-4037-8379-F31C7A36680E)";
        sender["participationtypemask"] = 1; //From

        //ActivityParty (To)
        var receiver1 = {};
        receiver1["partyid_account@odata.bind"] = "/accounts(B386D403-F7AD-E511-80DC-A45D36FC4F90)";
        receiver1["participationtypemask"] = 2; //To
        //receiver["addressused"] = "roohi@dyn20161.onmicrosoft.com";

        var receiver2 = {};
        receiver2["partyid_contact@odata.bind"] = "/contacts(DFE54660-37CD-E511-80DE-6C3BE5A831DC)";
        receiver2["participationtypemask"] = 2; //To

        var receiver3 = {};
        receiver3["partyid_lead@odata.bind"] = "/leads(ED81F0D9-37CD-E511-80DE-6C3BE5A831DC)";
        receiver3["participationtypemask"] = 2; //To

        //add this to collection
        parties.push(sender);
        parties.push(receiver1);
        parties.push(receiver2);
        parties.push(receiver3);

        //pass parties[] to phonecall_activity_parties
        JSONPhone["phonecall_activity_parties"] = parties;

        //Whole Number
        JSONPhone["actualdurationminutes"] = 25; //Duration

        //Two Options
        JSONPhone["directioncode"] = true;//Direction : 0-->False/Incomming, 1-->True/Outgoing

        //convert JSON object to string
        stringJSONPhone = JSON.stringify(JSONPhone);

        //url for ajax request to create phonecall activity
        urlPhone = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/phonecalls";

        //ajax request to create phonecall activity
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            url: urlPhone,
            data: stringJSONPhone,
            beforeSend: function (CreatePhoneCallActivityRequest) {
                CreatePhoneCallActivityRequest.setRequestHeader("Accept", "application/json");
                CreatePhoneCallActivityRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                CreatePhoneCallActivityRequest.setRequestHeader("Prefer", "odata.include-annotations=*");
                CreatePhoneCallActivityRequest.setRequestHeader("OData-MaxVersion", "4.0");
                CreatePhoneCallActivityRequest.setRequestHeader("OData-Version", "4.0");
            },
            //Success Callback Function
            success: function (data, taxtStatus, getPhoneCallActivityResponse) {
                //get Response from Created Record
                phonecallId = getPhoneCallActivityResponse.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record 
                phonecallId = phonecallId.split(/[()]/);
                phonecallId = phonecallId[1];

                //Display Enttity ID of Created Record
                Xrm.Utility.alertDialog("Entity ID : " + phonecallId);

            },
            //Error Callback Function
            error: function (CreatePhoneCallActivityRequest, textStatus, errorThrown) {
                Xrm.Utility.alertDialog("Something Wrong in Script...:(");
            }
        });
    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}

Conclusion:

Lookup, Regarding and Activity parties being special complex field need to be set by providing a reference to the entity type that you intend to set. The field name also includes a reference to the entity as can be seen in the sample code above. This differs from the way it used to be done earlier where entity type used to be provided as a property of the Lookup object instead of in the field name itself.

Accounting inside your Dynamics CRM..try today. Dynamics CRM and QuickBooks Integration.

Impersonation available using WEB API in Dynamics CRM 2016

$
0
0

Introduction:

Microsoft Dynamics CRM online 2016 update and Dynamics CRM 2016 (on-premises) has introduced a new concept called the Web API. This can be used across a wide variety of programming languages, platforms, and devices. One of the features of Web API is Impersonation.

Back in the days of CRM 4, Impersonation through scripting was supported by including the impersonation details in the header of the SOAP request.

Later this feature was removed and there was no way to impersonate a user through Scripting.

Impersonation is used when you want to execute business logic (code) on behalf of another CRM user. This is necessary because the CRM Web services can be called by various clients and services on behalf of a CRM user. Impersonation involves two different users where User (X) is used for executing the code to perform some tasks on behalf of another user (Y).

Walkthrough of Impersonation through Script

The User account (X) has to be given the prvActOnBehalfOfAnotherUser privilege to perform the task.

In order to impersonate a user through the Web API, you need to add ‘MSCRMCallerID’ key with GUID of the impersonated user. In the below example, a new contact entity is created on behalf of the user with systemuserid B65AB846-7EBE-E511-80DF-00155D06F307.

Here’s the code which helps you to impersonate a user through the Web API.

function impersonateUserReq()
{
    var userID = null;

    try {

        // create the contact object
        var contact = new Object();
        contact.firstname = "FirstName";
        contact.lastname = "LastName";
        contact.accountrolecode = 2;
        contact.creditonhold = false;
        contact["parentcustomerid_account@odata.bind"] = "/accounts(89C202DF-B1AF-E511-80E9-00155D06D000)"

        ///set the impersonateUser userid -  
        userID = "B65AB846-7EBE-E511-80DF-00155D06F307";

        Inogic.ApiLib.impersonateUser("contacts", contact, userID,
           impersonateUserSuccess,
           impersonateUserError);
    } catch (e) {
        showMessage(e.message);
    }
}
      // this Actual ajax request function is used to create the record and impersonate the user
            impersonateUser: function (entitySetName, entity,userId, successCallback, errorCallback) {

                var jsonEntity = null;

                try {

                    //create json object
                    var jsonEntity = window.JSON.stringify(entity);

                    //create AJAX request
                    $.ajax({
                        type: "POST",                      
                        contentType: "application/json; charset=utf-8",
                        datatype: "json",
                        url: encodeURI(this.getWebAPIPath() + entitySetName),
                        data: jsonEntity,
                        beforeSend: function (xhr) {
                            //Specifying this header ensures that the results will be returned as JSON.            
                        
                            xhr.setRequestHeader("MSCRMCallerID", userId);
                            xhr.setRequestHeader("Accept", "application/json");
                            xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                            xhr.setRequestHeader("OData-MaxVersion", "4.0");
                            xhr.setRequestHeader("OData-Version", "4.0");
                        },
                        success: function (data, textStatus, xhr) {

                            //call successCallback
                            successCallback(xhr.getResponseHeader("OData-EntityId"));
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            errorCallback(Inogic.ApiLib.errorHandler(xhr));
                        }
                    });
                } catch (e) {
                    throw new Error(e);
                }
            },

In the above code, the only addition is the following line of code

   xhr.setRequestHeader("MSCRMCallerID", userId);

Once the callerid is set, the record is created using the privileges that is assigned to the user specified in the callerid rather than the logged in user.

Conclusion:

On a concluding note, impersonation helps to perform operations on behalf of other users if the system account running the code has the necessary privileges.

You may also like to read : Make your Dynamics CRM life easy with Inogic Dynamics CRM Solutions.

Set Values of all Data Types using Web API in Dynamics CRM Through C#

$
0
0

Introduction:

With the release of Microsoft Dynamics CRM 2016, Web API which was introduced offers a development experience across many devices, languages and platforms.

In this blog we will take a look at how to set the all the datatypes in the CRM using C# through a windows application and using Web API.

You may refer this blog for connecting the CRM through the Web API.

Sample code to create an Account Entity Record with all Data Types:

//Initialize the WebAPIHandler class on Load of the Form as seen below:

//Global Variable of Class WebApiHandler
WebApiHandler _webAPIHandler=null;
//Method which Waits for all of the provided Task objects(i.e. Start Method in our case) to complete execution
private void CRUD_Load(object sender, EventArgs e)
{         
  Task.WaitAll(Task.Run(async () => await Start()));
}

private async Task Start()
{
  //Initialize the WebAPIHandler class
 webAPIHandler    = new WebApiHandler();
}

//Button click code which creates the Account record.
private void btnCreate_Click(object sender, EventArgs e)
{
            string recordId = string.Empty;

            //A Json Object used to create account record
            JObject account = null;

            //Request Uri to store the accounts path 
            string requestUri = "api/data/v8.0/accounts";

            try
            {
                //Get the Account Object
                account = CreateAccountRecordObject();

                //WebAPI Handler method call to Create Record
                recordId = _webAPIHandler.CreateRecord(account, requestUri);         
     }
            catch (Exception err)
            {

                throw new Exception(err.Message);
            }

        }

    	 /// <summary>
        /// Create Account Record Object
        /// </summary>
        /// <returns></returns>
        private JObject CreateAccountRecordObject()
        {
            JObject account = null;
            try
            {
                account = new JObject();

                //String Value
                account["name"] = "Sid Test Co";//Account Name

                //Optionset
                account["accountcategorycode"] = "2"; //Category : 1--> Preferred Customer, 2--> Standard

                //Two Options
                account["donotsendmm"] = false; //Marketing Materials : 0-->False/Send, 1-->True/Do Not Send

                //Whole number
                account["numberofemployees"] = 100;//Number of Employees

                //Custom Decimal Field
                account["new_creditrate"] = 2.25;//Decimal Number (Custom Field) 

                //Lookup
                //Setting the Primary Contact
                account["primarycontactid@odata.bind"] = "/contacts(E15C03BA-10EC-E511-80E2-C4346BAD87C8)"; //Primary Contact

                //setting the Transaction Currency
                account["transactioncurrencyid@odata.bind"] = "/transactioncurrencies(63D588A2-10EC-E511-80E2-C4346BAD87C8)"; //Currency

                //Currency/Money Field
                account["creditlimit"] = 1000; //Currency Limit

                //Custom Date Only Field
                account["new_effectivedate"] = DateTime.Now; //Date Only (Custom Field)


               
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }
            return account;
        }

Sample code to create an Activity & set Activity Party:

/// <summary>
        /// To Create the Phone Call Record
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreatePhoneCall_Click(object sender, EventArgs e)
        {
            //Request Uri to store the accounts path 
            string requestUri = "api/data/v8.0/phonecalls";
            string recordId = string.Empty;
            try
            {
                //Create Phone Call Object
                JObject phoneCall = CreatePhoneCall();
                //WebAPI Handler method call to Create Record
                recordId = _webAPIHandler.CreateRecord(phoneCall,requestUri);
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }

        }


        /// <summary>
        /// Create PhoneCall Object
        /// </summary>
        /// <returns></returns>
        private JObject CreatePhoneCall()
        {
            //create activity party collection
            JArray parties = new JArray();

            //create JSON object 
            JObject jsonPhoneCall = new JObject();


            try
            {
                //set fields using JSON object
                //Single line of text
                jsonPhoneCall["subject"] = "Test Phone Call" + DateTime.Now.ToShortDateString(); //Subject

                //Single line of text & format of phone 
                jsonPhoneCall["phonenumber"] = "4565898756"; //Phone Number

                //Multiple Line of Text
                jsonPhoneCall["description"] = "Phone Call Activity for Testing Purpose only...!"; //Description

                //Date and Time
                jsonPhoneCall["scheduledend"] = DateTime.Now; //Due

                //Lookup
                jsonPhoneCall["regardingobjectid_account@odata.bind"] = "/accounts(4B47AA19-88F3-E511-80E6-C4346BACF5C0)"; //Regarding is an account

                //ActivityParty (From)
                JObject sender = new JObject();
                sender["partyid_systemuser@odata.bind"] = "/systemusers(2e68e212-c82d-4bc6-9493-fbd80204a763)";
                sender["participationtypemask"] = 1; //From

                //ActivityParty (To)
                JObject receiver1 = new JObject();
                receiver1["partyid_account@odata.bind"] = "/accounts(4B47AA19-88F3-E511-80E6-C4346BACF5C0)";
                receiver1["participationtypemask"] = 2; //To
                 JObject receiver2 = new JObject();
                receiver2["partyid_systemuser@odata.bind"] = "/systemusers(2e68e212-c82d-4bc6-9493-fbd80204a763)";
                receiver2["participationtypemask"] = 2; //From


                //Add this to collection
                parties.Add(sender);
                parties.Add(receiver1);
                parties.Add(receiver2);


                //pass parties[] to phonecall_activity_parties
                jsonPhoneCall["phonecall_activity_parties"] = parties;

                //Whole Number
                jsonPhoneCall["actualdurationminutes"] = 25; //Duration

                //Two Options
                jsonPhoneCall["directioncode"] = true;//Direction : 0-->False/Incoming, 1-->True/Outgoing 
            }
            catch (Exception error)
            {                
                throw new Exception(error.Message);
            }

            return jsonPhoneCall;

The __webAPIHandler.CreateRecord() method is in WebApiHandler class.

It is as below:

/// <summary>
   /// Method to Return the record ID after creating it in CRM
   /// </summary>
   /// <param name="record"></param>
        /// <param name="requestUrl"></param>
        /// <returns></returns>
        public string CreateRecord(JObject record, string requestUrl)
        {
            string recordId = string.Empty;
            try
            {
                //Create HttpClient object to send and receive Http Requests and Response
                using (HttpClient httpClient = GetHttpClientObject())
                {
                    //Http Request needed to be sent by the HttpClient
                    HttpRequestMessage requestMessage = GetHttpRequestMessage(HttpMethod.Post, requestUrl, record);

                    //Send the HttpRequest
                    Task<HttpResponseMessage> response = httpClient.SendAsync(requestMessage);

                    //Wait till the Response Execution is complete
                    response.Wait();

                    //If the response is Successfully executed then it will return the value true
                    if (response.Result.IsSuccessStatusCode)
                    {
                        _recordUrl = response.Result.Headers.GetValues("OData-EntityId").FirstOrDefault();
                        splitRetrievedData = _recordUrl.Split('[', '(', ')', ']');

                        recordId = splitRetrievedData[1];

                    }
                }
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }

            return recordId;
        }

For the methods GetHttpClientObject(),GetHttpRequestMessage you may refer this blog.

To get the JObject, JArray i.e Json Objects you need to add reference to the Newtonsoft.Json.You may add it through Nuget using this command Install-Package Newtonsoft.Json.

Conclusion:

Hope the above code helps to set all the data types in Dynamics CRM.

Now export your Dynamics CRM Reports to word, excel or pdf in just 1 click with Click2Export

Executing Predefined Queries in Dynamics CRM using Web API through Scripts

$
0
0

Introduction:

What do you mean by Predefined Query?

System Views created in the CRM contains an inbuilt query which displays the results satisfying the Query mentioned in the view.

For e.g. “Active Contacts” an OOB system view.

Also, Users can create their views in Advance Find by specifying their criteria’s and save it giving any custom name.

These queries are known as Predefined Queries.

Using Web API we can retrieve and execute these Predefined Queries in the below way:

First in order to execute the Query we require the Query ID which we can retrieve in below manner:

There are be 2 types of Query in general:

  1. SavedQuery: Contains the SystemDefined View for an Entity. These views are stored in SavedQuery entity.
  1. UserQuery: Contains the Advanced Find Views created by the user for an Entity. These

Views are stored in UserQuery Entity.

To get the Query ID of System View the syntax is as shown below:

If it is System View then it is:

GET [Organization URI]/api/data/v8.0/savedqueries?$select=name,savedqueryid&$filter=name eq ‘Active Contacts’

If it is Custom View (User created view) then it is:

GET [Organization URI]/api/data/v8.0/userqueries?$select=name,userqueryid&$filter=name eq Custom Filter View’

Where

GET [Organization URI]: https://myorg.crm.dynamics.com [CRM Server Url]

Code to get the Query Id Variable:

//Method to retrieve the Query Id 
function retrieveQueryId(viewName, queryEntity, selectOptions) {
    var functionName = "retrieveQueryId";
    var viewId = "";
    try {
        //Get Client Url
        var clientUrl = Xrm.Page.context.getClientUrl();
        //Declare new XML HttpRequest Object
        var req = new XMLHttpRequest()
        //To Retrieve PreDefinedQuery Query
        req.open("GET", encodeURI(clientUrl + "/api/data/v8.0/" + queryEntity + "?" + selectOptions + "&$filter=name eq '" + viewName + "'"), false);
        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.send();

        if (req.status == 200) {

            var data = JSON.parse(req.response);
            var dat = data.value;
            //If record greater than 0 i.e. atleast 1 record found
            if (dat.length > 0) {
                //If it is System View
                if (queryEntity.toLowerCase() == "savedqueries") {
                    //read the first record
                    viewId = dat[0].savedqueryid;
                }//If it ia an User Query [Advanced Find]
                else if (queryEntity.toLowerCase() == "userqueries") {
                    //Read the first record
                    viewId = dat[0].userqueryid;
                }
            }


        }
        else {
            var error = JSON.parse(req.response).error;

        }

        return viewId;
    } catch (e) {
        alert(e.message);
    }
}

Where

  • viewName = View Name For e.g. “Active Contacts”
  • queryEntity = If it is System View then it is “savedqueries”. For Custom View it is “userqueries”
  • selectOptions = Columns which you want to select For e.g. “select=name,savedqueryid” for System View & “select=name,userqueryid

This functions returns the viewId of the Query record.

Now, we will see how to execute this Query after getting the ViewId:

Syntax:

If it is System View then it is:

GET [Organization URI]/api/data/v8.0/contacts?savedQuery=00000000-0000-0000-00aa-000010001002

If it is Custom View (User created view) then it is:

GET [Organization URI]/api/data/v8.0/contacts?userQuery=77444281-0010-1300-00aa-000010001002

Code to Execute the Query:

//Method executes the Query and returns Array of Records
function executeQuery(entityName, queryType, viewid) {
    var functionName = "executeQuery";
    var recordsFromView = null;
    try {

        //Get Client Url
        var clientUrl = Xrm.Page.context.getClientUrl();
        //Declare new XML HttpRequest Object
        var req = new XMLHttpRequest()

        if (viewid == "") {
            return;
        }
        //Sync Operation
        req.open("GET", encodeURI(clientUrl + "/api/data/v8.0/" + entityName + "?" + queryType + "=" + viewid), false);
        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.send();
        //If it is executed successfully
        if (req.status == 200) {

            var data = JSON.parse(req.response);
            recordsFromView = data.value;

        }
        else {
            var error = JSON.parse(req.response).error;
        }

        return recordsFromView;

    } catch (e) {
        alert(e.message);
    }
}

Where

  • clientUrl = CRM Server Url
  • entityName = The Entity whose View Id we have found
  • queryType = If it is a System View then queryType = “savedQuery”, For Custom View (user created) it is “userQuery”
  • viewid: ViewId which we retrieved above using retrieveQueryId() method.

Also, we can filter a particular View records based on its parent record.

For e.g.: There is System view “Open Opportunities”. We will filter the records based on a particular Account and retrieve the Open Opportunities related to this record.

Let’s see How we can achieve this below:

  1. Get the “Open Opportunities” view Id using retrieveQueryId() method which is shown above.
  2. After that call this function:

//Method to return records from View by Filtering it out based on the Parent Record
function executeFilterQuery(filterentityName, filterentityId, relationshipName,queryType, viewId) {
    var functionName = "executeQuery";
    var recordsFromView = null;
    try {

        //Get Client Url
        var clientUrl = Xrm.Page.context.getClientUrl();
        //Declare new XML HttpRequest Object
        var req = new XMLHttpRequest()

        if (viewId == "") {
            return;
        }
        //Sync Operation
        req.open("GET", encodeURI(clientUrl + "/api/data/v8.0/" + filterentityName + "(" + filterentityId + ")/" + relationshipName + "/?" + queryType + "=" + viewId), false);
        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.send();
        //If it is executed successfully
        if (req.status == 200) {

            var data = JSON.parse(req.response);
            recordsFromView = data.value;

        }
        else {
            var error = JSON.parse(req.response).error;
        }

        return recordsFromView;

    } catch (e) {
        alert(e.message);
    }
}

Where:

  • filterentityName: Parent record by which we need to filter the records. For e.g. Accounts in our case.
  • filterentityId: Parent Record Id
  • relationshipName: It is the collection-valued navigation property name. In our case “opportunity_parent_account”
  • queryType = If it is a System View then queryType = “savedQuery”, For Custom View (user created) it is “userQuery”
  • viewid: ViewId which we retrieved above using retrieveQueryId() method.

For Testing purpose you may call the below method on any event of the form:

//Method called on Load event
function startOperation() {

    //For System Views
    //Retrieve the View Id for the system view "Active Contacts"
    var systemQueryId = retrieveQueryId("Active Contacts", "savedqueries", "$select=name,savedqueryid")
    var queryRecords = executeQuery("contacts", "savedQuery", systemQueryId);

    //For User Created Views
    //Retrieve the View Id for the user created view "User Created Custom View"
    var customQueryId = retrieveQueryId("User Created Custom View", "userqueries", "$select=name,userqueryid")
    var customQueryRecords = executeQuery("contacts", "userQuery", customQueryId);


    //To Execute Views By filtering it based on parent record

    //Retrieve the View Id for the system view "Active Contacts"
    var filterviewId = retrieveQueryId("Open Opportunities", "savedqueries", "$select=name,savedqueryid");

    //Retrieve the Opportunities record that belong to particular Account
    var oppRecords = executeFilterQuery("accounts", "D8747EC1-A6F5-E511-80E2-C4346BAC339C", "opportunity_parent_account","savedQuery", filterviewId);

}

 Conclusion:

In this way we can execute Predefined Queries using Web API through Scripts.

Lets have a quick glimpse of new exciting features coming up in Maplytics May Release.

Web API Enhancements in Dynamics CRM Update 1

$
0
0

Introduction:

Microsoft Dynamics CRM 2016 introduced a new concept called Web API which can be used across wide variety of devices, programming languages and platforms. With the release of Update 1 for CRM 2016, few enhancements were added in this. In this blog, explained about Enhancements of Web API which is more helpful for the Developers.

Mainly, there are two enhancements released for the Web API Queries.

1. Filtering records based on the Parent entity Attribute

In one of our earlier blog, we have explained how to read the records based Lookup field using prefix “underscore” and suffix “value”. But, now with Microsoft Dynamics CRM 2016 update 1 we can filter the records using Parent entity Attribute.

Suppose, if we want to retrieve the opportunities of a particular Account then we can use the Lookup field name and primary attribute of the Parent entity which helps to retrieve the Opportunities of that Account.

Refer below Query for above example:

Query:

https://[OrganizationURI]/api/data/v8.1/opportunities $select=name&$filter=parentaccountid/accountid%20eq%205A544BE0-6217-E611-80DE-C4346BDDC0A1

Description:

parentaccountid: It is the lookup field name on the Opportunity entity.

acountid: It is primary attribute of the Account entity.

Response:Web API Enhancements in Dynamics CRM

Also, you can refer the below code to run above query using Ajax request:

//this below code snippet retrieves opportunities of particular Account

function retrieveOpportunities() {
    try {

        //query
        var oDataUrl = Xrm.Page.context.getClientUrl() + "/api/data/v8.1/opportunities?$select=name&$filter=parentaccountid/accountid%20eq%205A544BE0-6217-E611-80DE-C4346BDDC0A1";

        //ajax request to retrieve the opportunities of particular account
        $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            url: oDataUrl,
            beforeSend: function (xhr) {
                xhr.setRequestHeader("Accept", "application/json");
                xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                xhr.setRequestHeader("OData-MaxVersion", "4.0");
                xhr.setRequestHeader("OData-Version", "4.0");

                xhr.setRequestHeader("Prefer", "odata.include-annotations=*");

            },
            success: function (data, textStatus, xhr) {
                if (data != null) {

                    if (data.value[0].name != null) {
                        var opportnutyName = data.value[0].name;
                    }


                }
            },
            error: function (xhr, textStatus, errorThrown) {
                Xrm.Utility.alertDialog(xhr.statusText);
            }
        });

    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}

Note: We can only filter the records based on the Primary Attribute of the Parent entity.

2. Retrieve Parent Entity attributes by using expand command.

As same in our earlier blog, we have explained that we can read the parent entity attributes but in that there was a limitation that we can query for the single record and not for the collection of records. Now, with the CRM 2016 update 1 we can read the Parent entity attributes in the collection of records using the below query. Suppose, if we are retrieving the all Opportunities and also need to retrieve Account’s City then we can use the below query.

Refer below Query for above example:

Query:

https://[OrganizationURI]/api/data/v8.1/opportunities?$select=name&$expand=parentaccountid($select=address1_city)

Description:

                expand: It is command to retrieve the parent entity attributes.

                parentaccountid: It is lookup field name on the Opportunity entity.

                address1_city: It is field name of the parent entity which is to be retrieved.

Response:Web API enhancemnets

Conclusion:

Hope this two enhancement added in Web API Query will be helpful for developers.

We will cover more about Web API in our coming blogs.

Before you move on to the next post, have a look at Click2Clone – New Productivity add-on by Inogic.

Execute Web API request using Angular JS in Dynamics CRM

$
0
0

Introduction

In our earlier blogs of  Web API introduced in Dynamics CRM 2016, we have explained different requests and functions of Web API to querying and performing operations in Dynamics CRM.

This blog will show you how to execute Web API request using Angular JS.

This article would be helpful for those who have knowledge of Angular JS and now want to know how to use Angular JS to perform operations in Dynamic CRM.

Angular JS provides in-built service “$http” that facilitates communication with the remote HTTP servers via XMLHttpRequest object or via JSONP. In JQuery, $.ajax is used for same purpose.

So, we can use “$http” service to execute Web API request.

Below is the code snippet that executes Web API function:

$http({
                url: encodeURI(Xrm.Page.context.getClientUrl() + "/api/data/v8.0/RetrieveVersion()"),
                dataType: 'json',
                method: 'GET',
                headers: {
                    "Content-Type": "application/json"
                }
            }).success(function (response) {
                successCallback(response.Version);
            })
        .error(function (error) {
            errorCallback(error);
        });

You can see that, we pass Web API request to retrieve version of Dynamics CRM to URL. Execute “RetrieveVersion()” function, similarly you can execute other Web API functions like “WhoAmI()”, ”GetDefaultPriceLevelRequest()”, etc.

Below is the code snippet that query Dynamics CRM data,

$http({
                url: encodeURI(Xrm.Page.context.getClientUrl() + "/api/data/v8.0/accounts?$select=name&$top=3"),
                dataType: 'json',
                method: 'GET',
                headers: {
                    "Accept": "application/json",
                    "OData-MaxVersion": "4.0",
                    "OData-Version": "4.0",
                    "Prefer": "odata.maxpagesize=3"
                }
            }).success(function (response) {
                successCallback(response);
            })
       .error(function (error) {
           errorCallback(error);
       });

In this code, we have passed Web API query to select top 3 accounts. Here, the only difference between above code and the code that executes Web API function is URL and headers.

Conclusion:

If you are developing an application for Dynamics CRM using Angular JS, we can use $http service to get Dynamics CRM data or perform operations in Dynamics CRM.

Completed  with Dynamics CRM implementation? Whats next? Monitor User Adoption!


Retrieve, Update and Delete Record Using Alternate Key in Dynamics CRM Web API

$
0
0

Before Alternate key concept was introduced in Dynamics CRM it used to be the only GUID of the record which was used to retrieve, update or delete any record. Hence we had to get the record GUID first for any retrieve, update or delete operation. But with the introduction of Alternate keys concept this overhead of getting record GUID went away as we got an alternative way to create any field as Alternate Key and use it. Let’s see how we can perform these operations using Web API now with the help of Alternate keys.

Delete operation in Web API using Alternate key:

function DeleteEntityRecord() {
    var functionName = "DeleteEntityRecord";
    try {
        //get Server url
        var serverURL = Xrm.Page.context.getClientUrl();
        
        var xhr = new XMLHttpRequest();
        
        xhr.open("DELETE", serverURL + "/api/data/v8.0/accounts(accountnumber='AFFSE9IK′)')", true);
        xhr.setRequestHeader("Accept", "application/json");
        xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        xhr.setRequestHeader("OData-MaxVersion", "4.0");
        xhr.setRequestHeader("OData-Version", "4.0");
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                xhr.onreadystatechange = null;
                if (this.status == 204) {
                    //show alert
                    Xrm.Utility.alertDialog('Record Deleted Successfully.');
                }
                else {
                    var error = JSON.parse(this.response).error;
                    //show error
                    Xrm.Utility.alertDialog(error.message);
                }
            }
        };
        xhr.send();
    } catch (e) {
        Xrm.Utility.alertDialog(functionName + (e.message || e.description));
    }
}

In above operation “accountnumber” is Alternate key using which we have performed delete operation.

Update operation in Web API using Alternate key:

function UpdateEntityRecord() {
    var functionName = "UpdateEntityRecord";
    try {
        //get Server url
        var serverURL = Xrm.Page.context.getClientUrl();

        var xhr = new XMLHttpRequest();

        xhr.open("PATCH", serverURL + "/api/data/v8.0/contacts(emailaddress1='Adrian@adventure-works.com')", true);
        xhr.setRequestHeader("Accept", "application/json");
        xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        xhr.setRequestHeader("OData-MaxVersion", "4.0");
        xhr.setRequestHeader("OData-Version", "4.0");
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                xhr.onreadystatechange = null;
                if (this.status == 204) {
                    //show alert
                    Xrm.Utility.alertDialog('Record Updated Successfully.');
                }
                else {
                    var error = JSON.parse(this.response).error;
                    //show error
                    Xrm.Utility.alertDialog(error.message);
                }
            }
        };
        var objContact = {};
        objContact.firstname = "Sam";
        objContact.lastname = "Dsouza";


        var body = JSON.stringify(objContact);
        xhr.send(body);
    } catch (e) {
        Xrm.Utility.alertDialog(functionName + (e.message || e.description));
    }
}

In above operation “emailaddress1” is Alternate key using which we have performed update operation.

Retrieve operation in Web API using Alternate key:

function getEntityByAlternateKey() {
    try {
        var clientUrl = Xrm.Page.context.getClientUrl();
        var xhr = new XMLHttpRequest();
        
        xhr.open("GET", encodeURI(clientUrl + "/api/data/v8.0/contacts(mobilephone=’9568565458′)"), true);

        // For Multiple Alternate keys use like this
        //req.open("GET", encodeURI(clientUrl + "/api/data/v8.0/contacts(mobilephone=’9568565458′,emailaddress1=’Adrian@adventure-works.com’)"), true);

        xhr.setRequestHeader("Accept", "application/json");
        xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        xhr.setRequestHeader("OData-MaxVersion", "4.0");
        xhr.setRequestHeader("OData-Version", "4.0");
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                xhr.onreadystatechange = null;
                if (this.status == 200) {
                    var data = JSON.parse(this.response);
                    var dat = data.value;
                    for (var i = 0; i < dat.length; i++) {
                        var contId = dat[i].contactid;
                        Xrm.Utility.alertDialog("Entity Id : " + contId);
                    }
                }
                else {
                    var error = JSON.parse(this.response).error;
                    Xrm.Utility.alertDialog("Error retrieving Entity- " + error.message);
                }
            }
        };

        xhr.send();
    } catch (e) {
        Xrm.Utility.alertDialog("Error in getting Entity by alternate key – " + e.description);
    }
}

In above operation “mobilephone” is Alternate key using which we have performed retrieve operation.

In this way Alternate keys concept can be used for different operations like to retrieve, update, or delete any record.

Coming to CRMUG SUMMIT? Join us at Booth # 742!

Execute the Global Action Using Web API in Dynamics CRM

$
0
0

Introduction:

We have already discussed how to perform entity specific custom action using Web API in one of our earlier blog. But when we want an action to be performed on multiple entities, we need to create a global action.

Create global action:-

  1. Go to Settings → Processes → Click New then select category as “Action” and entity as “None(global)” as shown in below screenshot.Create global action
  2. Create the input argument (i.e InputParameter) and output argument (i.e. OutputParameter) as per below screenshot. Save and Activate the action. Create the input argument

Execute Global Action using Web API:-

Execute the created global action using Web API.
//get the current organization name
var serverURL = Xrm.Page.context.getClientUrl();
//query to send the request to the global Action 
var query=”new_GlobalAction”;
//set the current loggedin userid in to _inputParameter of the 
_InputParameter=Xrm.Page.context.getUserId();
 
//Pass the input parameters of action
var data = {
"InputParameter": _ InputParameter
};
//Create the HttpRequestObject to send WEB API Request 
var req = new XMLHttpRequest(); 
//Post the WEB API Request 
req.open("POST", serverURL + "/api/data/v8.0/”+query+", 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 /* complete */ ) { 
req.onreadystatechange = null; 
if (this.status == 200) { 
//You can get the output parameter of the action with name as given below
result = JSON.parse(this.response);
Xrm.Page.getAttribute(“Fieldname”).setValue(Result.OutputParameter);
} else { 
var error = JSON.parse(this.response).error; 
alert(error.message); 
} 
} 
}; 
//Execute request passing the input parameter of the action 
req.send(window.JSON.stringify(data));
}

Note:

To execute the global action you only need to pass Action Name “new_GlobalAction” shown in the above code

req.open(“POST”, serverURL + “/api/data/v8.0/”+query+”, true);

But to perform entity specific custom action you need to pass the EntityName and Primary id of record as

“account(” + Xrm.Page.data.entity.getId() + “)/Microsoft.Dynamics.CRM.new_EntityAction ”.

Conclusion:

Using the above code, global action can be performed. You can perform this action on multiple entities using Web API.

Wish to Visualize your Dynamics CRM Data on Map? Try Maplytics – Dynamics CRM + Maps.

Qualify Lead using Web API in Dynamics 365

$
0
0

Introduction

With the release of Dynamics 365, Microsoft has introduced many new actions using Web API. One of the important action that has been introduced in this release is “QualifyLead” in Web API.

Execution of this action using Web API qualifies a lead and creates a contact, account, and opportunity that will be linked to the originating lead record.

Below are the required parameters for executing this action:

  • CreateAccount: This is of Type Boolean i.e. value can be passed as true or false. It specifies whether an account should be created after qualifying a lead or not.
  • CreateContact: This is of Type Boolean i.e. value can be passed as true or false. It specifies whether a contact should be created after qualifying a lead or not.
  • CreateOpportunity: This is of Type Boolean i.e. value can be passed as true or false. It specifies whether an opportunity should be created after qualifying a lead or not.
  • Status: This is of Type Int and value can be passed as the value of the corresponding Status Reason for the Status Qualify of the lead entity.

Now let’s see how we can programmatically execute this request using Web API.

Code snippet:

function qualifyLead(leadId, clientUrl) {
    var functionName = "qualifyLead >>";
    var query = "";
    try {

        //Define the query to execute the action
        query = "leads(" + leadId.replace("}", "").replace("{", "") + ")/Microsoft.Dynamics.CRM.QualifyLead";

        //pass the parameters required
        var data = {
            "CreateAccount": true,
            "CreateContact": true,
            "CreateOpportunity": true,
            "Status":3
        };

        //Create request
        var req = new XMLHttpRequest();
        req.open("POST", clientUrl + "/api/data/v8.2/" + query, 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 /* complete */) {
                req.onreadystatechange = null;

                if (this.status == 200 || this.status == 204) {
                    //success callback this returns null since no return value available.
                    var result = JSON.parse(this.response);

                } else {
                    //error callback
                    var error = JSON.parse(this.response).error;
                }
            }
        };
        req.send(JSON.stringify(data));

    } catch (e) {
        throwError(functionName, e);
    }
}

Conclusion

Microsoft has introduced many new features and enhancements with the release of Dynamics 365. This blog focusses on one of the new actions introduced in Dynamics 365 i.e. “QualifyLead” in Web API.

Visit our blogs to keep yourself updated with latest Dynamics 365 features/news/technology!

Execute Action with “EntityCollection” Parameter using Web API in Dynamics 365

$
0
0

Introduction

Recently, we had a requirement where we wanted to Execute Custom Action in Dynamics CRM by passing “EntityCollection” type parameter using Web API. We have discussed how to execute the action using Web API in one of our earlier blog. However, in this blog we just explained executing action with string parameter.

Here we are going to focus on executing action with “EntityCollection” parameter using Web API.

You can see below that we have created a Custom Action:

Dynamics CRM Web API

Below code snippet will help you to Execute Action using Web API:

function CallCustomActionWithEntityCollectionParameter() {
    try {

        var reqName = "new_Approve";
        var clientUrl = Xrm.Page.context.getClientUrl();
        var parameters = {
           "Accounts"://EntityCollection parameter
             [
                  {
                      "@odata.type": "Microsoft.Dynamics.CRM.account",//entity type
                      "accountid": "C4CA0B66-59B9-E611-8106-C4346BDC0E01",//Record's guid
                      "name": "Test",//name field of the account entity
                      "accountnumber": "123"//accountnumber field of the account entity
                  },
                  {
                      "@odata.type": "Microsoft.Dynamics.CRM.account",
                      "accountid": "CD67D78E-16BB-E611-8109-C4346BDC3C21",
                      "name": "Test2",
                      "accountnumber": "1234"
                  }
             ]
        };

        //Create request
        var req = new XMLHttpRequest();
        req.open("POST", clientUrl + "/api/data/v8.2/" + reqName, 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 /* complete */) {
                req.onreadystatechange = null;

                if (this.status == 200 || this.status == 204) {
                    //success callback   
                    console.log("Success");
                } else {
                    //error callback      
                    console.log("Error");
                }
            }
        };
        req.send(JSON.stringify(parameters));

    } catch (e) {
        alert(e.message);
    }
}

Conclusion:

This blog will help you to execute action by passing “EntityCollection” parameter using Web API in Dynamics 365.

Now export Dynamics 365 reports to multiple formats in mere one click using Click2Export!

Viewing all 19 articles
Browse latest View live