Archive

Archive for July, 2016

Complete a transaction and throw exception in CRM Plug-in

July 31, 2016 3 comments

Recently I was asked a question in my blog on how to achieve below scenario in plug-in.

  • User try to save Account record by providing data in multiple fields.
  • Create Plug-in should check whether any other Account already exists in CRM with provided data.
  • If match found, update the existing record and display “Cannot save the Account as Account with data already exists”
  • If no match found, create an Account.

Challenge:

  • If ‘Account’ match found, system should update matched Account and at the same time throw message “Cannot save the Account as Account with data already exists”.
  • To display message Plugin must throw Execution with message which would roll back the update operation.

Proposed Design:

  • Register a Plug-in on “PreCreateAccount” with following logic, if matching ‘Account’ already exists with input data.
  • To complete update operation,
    • Use “ExecuteMultipleRequest” with option “ContinueOnError = true” which completes transaction.
    • Instantiate ‘UpdateRequest’ and execute using “ExecuteMultipleRequest”
  • In next line, throw exception with message

Plug-in Code:

// Get the matched Account
Entity matchedAccount = new Entity(“account”);
UpdateRequest reqUpdate = new UpdateRequest();
reqUpdate.Target = matchedAccount;

// Use this to complete the update operation even on an exception
ExecuteMultipleRequest reqMultiple = new ExecuteMultipleRequest(){
Requests = new OrganizationRequestCollection(),
Settings = new ExecuteMultipleSettings(){
ContinueOnError = true,
ReturnResponses = false
}
};

// Add Update Request to Multiple Request.
reqMultiple.Requests.Add(reqUpdate);

// Trigger the Execute Multiple.
crmOrgService.Execute(reqMultiple);

// Use this to display message to user
throw InvalidPluginExecutionException(“Cannot save the Account as Account with data already exists”);

🙂

Categories: CRM Tags: , ,

‘http://event’ pop-ups with hosted controls of Hosting type ‘IE Process’ – USD

In my USD, I have a hosted control of type “IE Process”.

Hosted Control

Hosted Control

Whenever it gets loaded, I was getting “http://event” IE pop-up and its blocking configured events of Hosted control to be triggered.

Reason:

  • These popups occur in IE 11
  • When the protected mode of IE set to ‘Off’ for the Intranet Zone, which is a default setting of IE.

Fix:

  • Either change the “Hosting Type” of hosted control to “Internal WPF” (or)
  • ‘Turn On’ the protected mode for the Intranet zone.

Refer this article for more info.

🙂

Categories: USD Tags: , ,

Retrieve and Update record with alternate key using Web API – CRM 2016

July 1, 2016 1 comment

Alternative Keys are useful to retrieve or update the records without the need of GUID. It avoids the overhead of retrieving record’s GUID while update operation.

In conventional way, to update an Account record from external web application, you would need to get the GUID first and then update.

With alternate key, you can configure any of your field of type (Single Line of Text, Whole Number or Decimal Number) as Alternate key and use instead of GUID to retrieve or update.

We can have up to 5 different alternate keys per entity.

Sample C# code to update record with out GUID:

  • I configured “Account Number” as alternate key.
  • I have an Account with ‘Account Number’ as ‘Acct123’ and below is the code to update record. Notice that I did not provide the record GUID.

Entity account = new Entity(“account”, “accountnumber”, “Acct123”);
account[“name”] = “Rajeev Modified”;
service.Update(account);

Create an Alternate key

  • Go to Customization–> Entity–> Keys –> New
Create Alternate Key

Create Alternate Key

  • Click “Ok”
  • Wait for few seconds so that the background workflow complete creation of required indexes.

Jscript to retrieve using Alternate key:

  • Below is the script to retrieve a record with alternate key using web api.

function getAccountByAlternateKey() {
try {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
// Account Number as an ‘Alternate key’
req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/accounts(accountnumber=’Acct123′)“), true);
// If multiple keys as ‘Alternate key’
//req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/accounts(name=’Rajeev’,emailaddress1=’rajeev@live.com’)”), 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) {
var data = JSON.parse(this.response);
var dat = data.value;
for (var i = 0; i < dat.length; i++) {
var accountId = dat[i].accountid;
Xrm.Utility.alertDialog(“Account Id : ” + accountId);
}
}
else {
var error = JSON.parse(this.response).error;
alert(“Error retrieving Account- ” + error.message);
}
}
};

req.send();
} catch (e) {
alert(“Error in getAccountByAlternateKey – ” + e.description);
}
}

JScript to Update Record Using Alternate Key

function updateAccountByAlternateKey() {
try {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
// Account Number as an ‘Alternate key’
req.open(“PATCH“, encodeURI(clientUrl + “/api/data/v8.0/accounts(accountnumber=’Acct123′)“), 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 == 204) {
var accountUri = this.getResponseHeader(“OData-EntityId”);

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

Xrm.Utility.alertDialog(“Updated Account ID : ” + accountID);
}
}
};

// Set Account Object
var objAccount = {};
objAccount.name = “Rajeev Modified”;
objAccount.revenue = 123456;

//convert JSON object to string
var body = JSON.stringify(objAccount);

req.send(body);
} catch (e) {
alert(“Error in updateAccountByAlternateKey – ” + e.description);
}
}

Refer article  for more details.

🙂

Categories: CRM 2016 Tags: , ,

JScript to Create record and its related record using Web API – CRM 2016

Below is the script snippet to create ‘Account’ record using Web API.

function createAccount() {
var clientUrl = Xrm.Page.context.getClientUrl();

var req = new XMLHttpRequest()
req.open(“POST”, encodeURI(clientUrl + “/api/data/v8.0/accounts”), 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.setRequestHeader(“Prefer”, “odata.include-annotations=*”);

// Set Account Object
var objAccount = {};
objAccount.name = “Rajeev Associates”;
objAccount.creditonhold = false;
objAccount.accountcategorycode = 1;
objAccount.revenue = 123456;

// Create new Contact and Set as ‘Primary Contact’
objAccount.primarycontactid = {};
objAccount.primarycontactid.firstname = “Hello”;
objAccount.primarycontactid.lastname = “Lobo”;

// Set existing Contact as ‘Primary Contact’
//objAccount[‘primarycontactid@odata.bind’] = “/contacts(” + { contact GUID } + “)”;

//convert JSON object to string

var body = JSON.stringify(objAccount);

req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 204) {
var accountUri = this.getResponseHeader(“OData-EntityId”);

// Get Account GUID
var accountID = accountUri.split(/[()]/);
accountID = accountID[1];

Xrm.Utility.alertDialog(“Created Account ID : ” + accountID);
}
}
};

req.send(body);
}

  • To set the lookup you need to fetch the Contact GUID first and set to ‘primarycontactid@odata.bind’. ‘@odata.bind’ is suffix and ‘primarycontactid‘ is the schema name of lookup.
  • Below is sample script to retrieve Contact GUID by Fullname

function getPrimaryContact() {
var clientUrl = Xrm.Page.context.getClientUrl();
var req = new XMLHttpRequest();
req.open(“GET”, encodeURI(clientUrl + “/api/data/v8.0/contacts?$select=fullname&$filter=fullname eq ‘John Miller'”), 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) {
var data = JSON.parse(this.response);
var dat = data.value;

// Loop through ‘Contact’ result set
for (var i = 0; i < dat.length; i++) {

// Get ‘Contact ID’ from Contact record.
var contactId = dat[i].contactid;
if (contactId) {

Xrm.Utility.alertDialog(“Contact ID : ” + contactId);
}
}
}
else {
var error = JSON.parse(this.response).error;
alert(“Error retrieving contact – ” + error.message);
}
}
};

req.send();
}

🙂

Categories: CRM 2016 Tags: , , ,