Archive

Archive for May, 2013

Associate Campaign with related items using Jscript – CRM 2011

We can associate 2 entity records having N:N relationship using “AssociateRequest” SDK message. (How to associate)

But you get below error when you try to associate a Campaign record with Campaign related items such as Marketing List, Product, or Salesliterature using “AssociateRequest” SDK message.

Associate is not supported for CampaignItem Platform

To associate a Campaign, we have an exclusive SDK message “AddItemCampaignRequest”.

Below is the Jscript to associate Campaign with related records

function associateCampaignItem (campaignId, associateRecordId, associateRecordSchemaName) {

var requestMain = “”

requestMain += “<s:Envelope xmlns:s=\”http://schemas.xmlsoap.org/soap/envelope/\”>”;

requestMain += ” <s:Body>”;

requestMain += ” <Execute xmlns=\”http://schemas.microsoft.com/xrm/2011/Contracts/Services\” xmlns:i=\”http://www.w3.org/2001/XMLSchema-instance\”>”;

requestMain += ” <request i:type=\”b:AddItemCampaignRequest\” xmlns:a=\”http://schemas.microsoft.com/xrm/2011/Contracts\” xmlns:b=\”http://schemas.microsoft.com/crm/2011/Contracts\”>”;

requestMain += ” <a:Parameters xmlns:c=\”http://schemas.datacontract.org/2004/07/System.Collections.Generic\”>”;

requestMain += ” <a:KeyValuePairOfstringanyType>”;

requestMain += ” <c:key>CampaignId</c:key>”;

requestMain += ” <c:value i:type=\”d:guid\” xmlns:d=\”http://schemas.microsoft.com/2003/10/Serialization/\”>” + campaignId + “</c:value>”;

requestMain += ” </a:KeyValuePairOfstringanyType>”;

requestMain += ” <a:KeyValuePairOfstringanyType>”;

requestMain += ” <c:key>EntityId</c:key>”;

requestMain += ” <c:value i:type=\”d:guid\” xmlns:d=\”http://schemas.microsoft.com/2003/10/Serialization/\”>” + associateRecordId + “</c:value>”;

requestMain += ” </a:KeyValuePairOfstringanyType>”;

requestMain += ” <a:KeyValuePairOfstringanyType>”;

requestMain += ” <c:key>EntityName</c:key>”;

requestMain += ” <c:value i:type=\”d:string\” xmlns:d=\”http://www.w3.org/2001/XMLSchema\”>” + associateRecordSchemaName + “</c:value>”;

requestMain += ” </a:KeyValuePairOfstringanyType>”;

requestMain += ” </a:Parameters>”;

requestMain += ” <a:RequestId i:nil=\”true\” />”;

requestMain += ” <a:RequestName>AddItemCampaign</a:RequestName>”;

requestMain += ” </request>”;

requestMain += ” </Execute>”;

requestMain += ” </s:Body>”;

requestMain += “</s:Envelope>”;

var req = new XMLHttpRequest();

 

var OrgServicePath = “/XRMServices/2011/Organization.svc/web”;

var serverUrl = Xrm.Page.context.getServerUrl() + OrgServicePath;

req.open(“POST”, serverUrl, true)

// Responses will return XML. It isn’t possible to return JSON.

req.setRequestHeader(“Accept”, “application/xml, text/xml, */*”);

req.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);

req.setRequestHeader(“SOAPAction”, “http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute&#8221;);

var successCallback = null;

var errorCallback = null;

req.onreadystatechange = function () { AddItemCampaignResponse(req); };

req.send(requestMain);

}

function AddItemCampaignResponse(req) {

if (req.readyState == 4) {

if (req.status == 200) {

alert(“Success”);

}

else {

alert(“Error – ” + req.responseXML);

}

}

}

How do I use

  • Lets try to associate ‘Campaign’ with ‘Marketing List’ item using above script
  • Pass the required arguments as specified below

    var campaignId = “”; //Campaign GUID

var marketinglistId = “”; //Marketinglist GUID

var schemaName = “”; // Marketinglist entity Schema Name

associateCampaignItem(campaignId, marketinglistId, schemaName);

Below is the C# code to form the ‘AddItemCampaignRequest’

var request = new AddItemCampaignRequest
{
    CampaignId = campaignId,
    EntityId = marketinglistId,
    EntityName = {Marketinglist entity Schema Name}
};

🙂

Consuming WCF service from Jscript using JQuery

I recently got a requirement to host a WCF service in Azure and consume it client side using Jscript.

In this article, I am providing details on how to consume WCF service from Jscript with the help of JQuery.

In below example, service is a simple “Products.svc” contain 1 method “GetProducts()” and returns List<Product> (“Product” is custom class)

WCF Service

  • Service Contract (IProductService.cs)

[ServiceContract(Namespace = “http://ABCproducts&#8221;,

Name = “IProductService”,

SessionMode = SessionMode.NotAllowed,

ProtectionLevel = ProtectionLevel.None)]

public interface IProductService{

[OperationContract]

[WebInvoke(

Method = “POST”,

BodyStyle = WebMessageBodyStyle.Wrapped,

RequestFormat = WebMessageFormat.Json,

ResponseFormat = WebMessageFormat.Json)]

List<Product> GetProducts();

}

[DataContract]

public class Product{

string id = string.Empty;

string name = string.Empty;

[DataMember]

public string ProductId{

get { return id; }

set { id = value; }

}

[DataMember]

public string ProductName{

get { return name; }

set { name = value; }

}

}

  • Service (ProductService.svc)

public List<Product> GetProducts(){

List<Product> products = new List<Product>();

Product P1 = new Product();

P1.Id = “1”;

P1.Name = “Mango”;

Product P2 = new Product();

P2.Id = “2”;

P2.Name = “Apple”;

products.Add(P1);

products.Add(P2);

return products;

}

  • Service Binding (Web.config)
    • Very important note is, the service endpoint has to be “webHttpBinding”; otherwise we get “Cannot process the message because the content type application\json was not the expected…” error.
    • webHttpBinding is the REST-style binding, where you can hit a service URL and get back a result in either XML or JSON from the service.
    webHttp Binding

    webHttp Binding

    • Add a “EndPointBehavior” with “webHttp” stack element.
webHttp Behavior

webHttp Behavior

    • Below is the service configuration mentioned in my web.config file

<services>

<service name=”ProductService”>

<endpoint address=”” behaviorConfiguration=”endPtBehaviorJSon

binding=”webHttpBinding” bindingConfiguration=”bindingWebHttp”

name=”wsBindingBFS” contract=”IProductService” />

</service>

</services>

<behaviors>

<endpointBehaviors>

<behavior name=”endPtBehaviorJSon“>

<webHttp />

</behavior>

</endpointBehaviors>

</behaviors>

Jscript

  • Since we are using JQuery, refer “JQuery.1.4.1.min.js” file
  • In this example we are getting output in json format. (Observe “dataType property mentioned as “json”)
  • getProducts” is the function which communicate to service and gets “Product” collection as response in JSon format.
  • The response comes in special format (i.e., WCF Service method name+Result)  (i.e, GetProductsResult)

function getProducts() {

var serviceURL = “http://{Server Name}/ProductService.svc/GetProducts“;

$.ajax({

type: “POST”,

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

url: serviceURL,

processData: false,

dataType: “json”,

//If the call succeeds

success:

function (response) {

retrieveProducts(response)

},

//If the call fails

error: function (XMLHttpRequest, textStatus, errorThrown) {

alert(“Error while retrieval – ” + XMLHttpRequest.responseText);

}

});

}

function retrieveProducts(response) {

// Result collection come as Response.{MethodName}+”Result”

if (response && response.GetProductsResult) {

$.each(response.GetProductsResult, function (i) {

alert(

“Product ID: ” + this.ProductId +

” Product Name: ” + this.ProductName);

});

}

}

Copy a security role programmatically – CRM 2011

In one of the requirement, we have to create a new security role by copying an existing role in a Plug-in.

The whole requirement break down to 3 steps

  1. Create a new security role
  2. Get all the existing role privileges by using “RetrieveRolePrivilegesRoleRequest
    1. RetrieveRolePrivilegesRoleResponse” contain, “RolePrivileges” property, with collection of privileges & access level
    2. Role Privilages

      Role Privileges

  3. Add the retrieved role privileges to the newly created role by using “AddPrivilegesRoleRequest

Below is the code for step 2 & 3

Guid existingRoleId = new Guid(“C85F0FFF-4C80-E211-A877-1CC1DE79B4CA”);

Guid newRoleId = new Guid(“B6690FFF-4C80-E211-A877-1CC1DE79B4CA”);

// Step 2

RetrieveRolePrivilegesRoleRequest getPrivilagesRequest = new RetrieveRolePrivilegesRoleRequest();

getPrivilagesRequest.RoleId = existingRoleId;

RetrieveRolePrivilegesRoleResponse privilagesResponse = (RetrieveRolePrivilegesRoleResponse)service.Execute(getPrivilagesRequest);

if (privilagesResponse != null && privilagesResponse.RolePrivileges != null){

// Step 3

AddPrivilegesRoleRequest addPrivilagesRequest = new AddPrivilegesRoleRequest();

addPrivilagesRequest.Privileges = privilagesResponse.RolePrivileges;

addPrivilagesRequest.RoleId = newRoleId;

AddPrivilegesRoleResponse addPrivilagesResponse = (AddPrivilegesRoleResponse)service.Execute(addPrivilagesRequest);

}

🙂

Unable to install CRM 2011 Report Extension – Reboot required error

I was getting below “Reboot Required” message when I tried to install “CRM 2011 Report Extension” (i.e., CRM2011-Bids-ENU-i386)

Installation cannot proceed

Installation cannot proceed

  • I restarted my machine and I retried to install, still I was getting same error.
  • As mentioned in the error message, I checked the log file under “C:\Users\{curr_user}\appdata\Roaming\Microsoft\MSCRM\Logs\BIDSExtensionsSetup.log” path, there it was written as

Reboot required — Key Found: HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce

Fix –

  • Seems a known issue
  • We need to delete the “RunOnce” key from “Registry” (Path – HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce)
  • Refer KB Article from Microsoft.

After deletion of “RunOnce” key from Registry, I was able to install CRM 2011 Report Extension.

🙂

Disabling controls in a section using JScript

We can’t disable a Section using “setDisabled(false)”, as Section is a container of controls.

Below is the logic to disable all the controls in a section

  • Loop through all the page controls
  • If the control’s parent is the specified section, disable the control

Below are the functions to disable controls in a Section. We need to pass “Section” object as parameter

function disableSectionFields(section) {

if (section) {

Xrm.Page.ui.controls.forEach(function (control, index) {

if (control && doesControlHaveAttribute(control)) {

if (control.getParent() === section) {

control.setDisabled(true);

}

}

});

}

}

// Validate if the control is not  IFrame/webresource/subgrid as we can’t disable them

function doesControlHaveAttribute(control) {

var controlType = control.getControlType();

return controlType != “iframe” && controlType != “webresource” && controlType != “subgrid”;

}

// Get the Section object by Tab name & Section name

function getSection(tabName, sectionName) {

var tab = Xrm.Page.ui.tabs.get(tabName);

if (tab) {

return tab.sections.get(sectionName);

}

return null;

}

How do I call

  • Assume my tab name is “tab_name” & section name is “section_name”
  • Get the section object and pass to the “disableSectionFields” function as below

var mySection = getSection(“tab_name”, “section_name”);

if (mySection) {

disableSectionFields(mySection);

}

🙂

Set desired form as default using script – CRM 2011

I have an “Account” entity with multiple forms (i.e.,4 forms). My requirement is to set particular form as default form based on some logic.

Below is the script to set desired form as default.

function setMyFormAsDefault() {

// Set the form name you want to set as default

var myDefFormName = “ABC”;

// Get all available forms

if (Xrm.Page.ui.formSelector.items.get()) {

var forms = Xrm.Page.ui.formSelector.items.get();

var formId, formName;

for (var indxForms = 0; indxForms < forms.length; indxForms++) {

formId = forms[indxForms].getId();

formName = forms[indxForms].getLabel();

// Check form name and if it matches set current form as Default

if (formName == myDefFormName) {

forms[indxForms].navigate();

break;

}

}

}

}

  • Xrm.Page.ui.formSelector.items.get()” give us all available forms of the current entity
  • getId() & getLabel() gives the form GUID and Form name
  • “navigate()” loads the selected form

🙂

Reading related records using OData and Jscript – CRM 2011

I have 1:N relationship between “Contact” entity and custom entity “Bikes” (i.e., 1 contact can have N no of Bikes).

If I want to read all “Bikes” along with my “Contact” information using OData service, I can use the “$expand” keyword of OData protocol.

Below is the generic function to prepare the OData URL and make a Asynchronous service call

function retrieveMultiple(odataSetName, select, filter, expand, successCallback) {

var serverUrl = Xrm.Page.context.getServerUrl();

var ODATA_ENDPOINT = “/XRMServices/2011/OrganizationData.svc”;

var odataUri = serverUrl + ODATA_ENDPOINT + “/” + odataSetName + “?”;

if (select) {

odataUri += “$select=” + select;

}

if (expand) {

odataUri += “&” + “$expand=” + expand;

}

if (filter) {

odataUri += “&” + “$filter=” + filter;

}

$.ajax({

type: “GET”,

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

datatype: “json”,

url: odataUri,

beforeSend: function (XMLHttpRequest) {

XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);

},

success: function (data, textStatus, XmlHttpRequest) {

if (successCallback) {

if (data && data.d && data.d.results) {

successCallback(data.d.results, textStatus, XmlHttpRequest);

}

else if (data && data.d) {

successCallback(data.d, textStatus, XmlHttpRequest);

}

else {

successCallback(data, textStatus, XmlHttpRequest);

}

}

},

error: function (XmlHttpRequest, textStatus, errorThrown) {

if (XmlHttpRequest && XmlHttpRequest.responseText) {

alert(“Error while retrieval of ” + odataSetName + ” ; Error – ” + XmlHttpRequest.responseText);

}

}

});

}

How do I use above function

  • Consider my “Contact” & “Bike” scenario and set required the columns and “expand” option and call the above “retrieveMultiple” function
  • Below is the function to define properties

function retrieveBikesByContactId() {

// Pass ‘Contact’ set name

var oDataSetName = “ContactSet”;

// Set Contact GUID

var contactId = {Contact GUID};

// Prepare filter

var filter = “ContactId eq guid'” + contactId + “‘”;

// Set expand (i.e., Relationship name of ‘Contact’ and ‘Bike’)

var expand = “honda_contact_honda_bikeinformation”;

// Column names of ‘Contact’ and ‘Bikes’

// Since Bike is related entity specify Bike columns as (Relationship name\column name) (i.e., honda_contact_honda_bikeinformation/honda_name)

var columns = “FullName,honda_contact_honda_bikeinformation/honda_name,honda_contact_honda_bikeinformation/honda_Year”;

retrieveMultiple(oDataSetName, columns, filter, expand, readDataOnSuccess);

}

  • After the success of data retrieval, parse the result using “readDataOnSuccess” method

function readDataOnSuccess(data, textStatus, XmlHttpRequest) {

if (data && data.length > 0) {

for (var indx = 0; indx < data.length; indx++) {

if (data[indx].honda_contact_honda_bikeinformation) {

              // Read the child entity records using “expand.results” (i.e., honda_contact_honda_bikeinformation.results)

var childResults = data[indx].honda_contact_honda_bikeinformation.results;

for (var indxChild = 0; indxChild < childResults.length; indxChild++) {

alert(childResults[indxChild].honda_name);

}

}

}

}

}

Use the “OData Query Designer” tool to get the “expand” name and column names

  • To get related entity record fields, click “One To Many” tab and choose the relationship
Get Related Entity Fields

Get Related Entity Fields

URL with Related records columns

URL with Related records columns

Related records result set

Related records result set