Thursday, 27 May 2021

Useful JScript syntax’s – ADX/Dynamics 365 Portals

 

Useful JScript syntax’s – ADX/Dynamics 365 Portals


CRM form script’s (i.e., Onload, OnSave, OnChange) won’t run on ADX/Dynamics 365 Entity Form’s.

What if we must Get/Set, Hide/Show or Enable/Disable controls based on business logic? We need to write custom script and add in “Custom JavaScript” section of “Entity Form”.

Custom Javascript

Custom Javascript

In this article, I am providing syntax’s to Get/Set attribute values and basic validations.

Get value:

Text Field:

Here ‘name’ is CRM field’s schema name.

  • var contactName=$(“#name”).val();

Look up

  • var lookupGUID = $(“#new_contactid”).val();
  • var lookupValue = $(“#new_ contactid_name”).val();
  • var entityName= $(“#new_contactid_entityname”).val();

Option Set

  • var userType = $(“#new_usertype”).val();

DateTime

  • var dobValue= $(“#new_dob”).val();
  • // Convert to date
  • var dob=new Date(dobValue);

Checkbox

Below is the script to determine whether the checkbox is checked or not

var isChecked = $(“#{field_name}”).is(“:checked”);
if (isChecked == true) {
alert(“Checked!”);
}
else if (isChecked == false) {
alert(“Unchecked!”);
}

Radio Button

Radio button renders as 2 controls. Below is the syntax to read which radio option has been checked.

var isOption1Checked = $(“#{field_name_0}”).is(“:checked”); //Returns true/false

var isOption2Checked = $(“#{field_name_1}”).is(“:checked”); //Returns true/false

Set Value:

Text Field

  • $(“#name”).val(“Rajeev Pentyala”);

Look up

  • $(“#new_contactid”).val(lookupId);
  • $(“#new_contactid_name”).val(lookupName);
  • $(“# new_contactid_entityname”).val(EntitySchemaName);

Option Set

Here ‘new_usertype’ is CRM field’s schema name.

  • $(“#new_usertype”).val(10000);

Checkbox

$(‘#{fieldname}’).prop(‘checked’, true);

Radio Button

// To set Radio 1 to ‘true’

$(‘#{fieldname_0}’).prop(‘checked’, true);

// To set Radio 2 to ‘true’

$(‘#{fieldname_1}’).prop(‘checked’, true);

Date time

Below is the snippet to set Date field to ‘Today’

// Get today()
var dateValue = new Date();
// Get date field
var dateField = $(“#new_mydatefield”);
var $displayField = dateField.nextAll(“.datetimepicker”).children(“input”);
var dateFormat = $displayField.attr(“data-date-format”);
dateField.val(moment.utc(dateValue).format(“YYYY-MM-DDTHH:mm:ss.0000000\\Z”));
$displayField.val(moment(dateValue).format(dateFormat));

Note: Portal uses Moment.js for Date operations.

Note

Get/Set statements need to wrap in Document’s Ready event.

$(document).ready(function() {
// $(“#name”).val(“Rajeev Pentyala”);
});

Enable/Disable Controls:

Lookup

  • It’s very tricky to Enable/Disable Lookup’s
  • Lookup control render as multiple components on ADX form, to disable lookup selection, we need to find the ‘Magnifier’ button and Hide it.

$(“#new_contactid_name”).parent().find(‘.input-group-btn’).hide(); // Find lookup’s Magnifier button and Hide it

Date

  • Below is the script to disable ‘Date’ control

// My Date field’s schema name is ‘new_dateofbirth’
var dateField = $(“#new_dateofbirth”);
// Get ‘Text’ field of Date Control
var displayField = dateField.nextAll(“.datetimepicker”).children(“input”);
// Get ‘Calendar’ Icon of Date Control
var dateIcon = dateField.nextAll(“.datetimepicker”).children(“span”);
// Make ‘Text’ field of Date Control Read-Only
displayField.attr(“readonly”, “readonly”);
// Hide ‘Calendar’ Icon
dateIcon.css(“display”, “none”);

Text

  • $(“#name”).prop(‘disabled’, true);

Hide/Show Controls:

–Option 1
// Hide
$(“#fieldname”).hide();
$(“#fieldname_label”).hide();
// Show
$(“#fieldname”).show();
$(“#fieldname_label”).show();

–Option 2
// Hide
$(“#fieldname”).closest(“tr”).hide();
// Show
$(“#fieldname”).closest(“tr”).show();

Make OOB Required Field Non-Required:

  • If the Field is OOB Required or set as Required using Metadata, below is the function to make field as Non-Required.
    • Note: OOB required field will have the validator naming convention as “RequiredFieldValidator” + fieldSchemaName
  • Make sure you pass field’s Schema Name to below function.

function makeOOBFieldNonMandatory(fieldSchemaName){

$.each(Page_Validators, function (index, validator) {

if (validator.id == “RequiredFieldValidator” + fieldSchemaName) {

Page_Validators.splice(index, 1);

}

});

$(“#” + fieldSchemaName+ “_label”).parent().removeClass(“required”);

}

  • To set custom validator, refer this article

Liquid Script Syntax’s:

  • Get current Portal User (i.e.,Contact) guid

$(document).ready(function () {

var portalUserId = ‘{{ user.Id }}’;

});

  • Get current Portal User (i.e.,Contact) Name

$(document).ready(function () {

var portalUserName = ‘{{ user.fullname}}’;

});

  • Check if current Portal User has a specific ‘Web Role’

$(document).ready(function () {

{% if user.roles contains ‘Administrators’%}
alert(“Current portal user has ‘Administrators’ web role”);
{% endif %}

});

  •  Check if User is logged-in or not

{% if user %}

// Logged-In User

{% else if %}

// Not logged In. Anonymous User

{% endif %}

Validations:

Custom Validation on ‘Submit’

  • On click of the ‘Submit’ button a function named webFormClientValidate is executed.
Validation-on-submit

Validation-on-submit

  • We can extend this method to add our custom validation logic.
  • In below example, I am preventing ‘Submit’, if Name is not ‘Rajeev’

if (window.jQuery) {
(function ($) {
if (typeof (webFormClientValidate) != ‘undefined’) {
var originalValidationFunction = webFormClientValidate;
if (originalValidationFunction && typeof (originalValidationFunction) == “function”) {
webFormClientValidate = function () {
originalValidationFunction.apply(this, arguments);
// Start custom validation.
// Prevent Submit if Name!=Rajeev
if ($(“#name”).val() != ‘Rajeev’) {
return false; // To prevent the form submit return false
}
// End custom validation.
return true;
};
}
}
}(window.jQuery));
}

Refer Adx portal’s blog on Custom JavaScript.

Session Timeout:

Following 2 keys need to be added to ‘Site Settings’ entity.

PSession_1

Name : Authentication/ApplicationCookie/ExpireTimeSpan
Value : The default amount of time cookie authentication sessions are valid for. Default: 24:00:00 (1 day). To set 30 minutes interval specify value as 00:30:00.

Name : Authentication/ApplicationCookie/LoginPath
Value : /SignIn
Description: Redirection onto the given login path after session timeout. We can configure our own custom Web Template and redirect up on session expiry.

Restrict ‘File Types’ during uploads:

  • To allow specific file types only, during the uploads from portal, provide configurations specified on screenshot on the portal’s ‘Entity Form’.
  • Make sure to check the ‘Restrict File To Accept Types’ checkbox.
  • In the ‘Accept’ field, specify the mimetypes of allowable file types separated by ,
    • image/jpeg,image/pjpeg,application/pdf,image/png

RestrictFileTypes

Monday, 24 May 2021

Console app with oAuth

CRUD Operation in Console Application using C# in Dynamics 365





public CrmServiceClient ConnectWithOAuth() { Console.WriteLine("Connecting to D365 Server..."); string authType = "OAuth"; string userName = "
XX@XXXX.onmicrosoft.com"; string password = "XXXXXXXX"; string url = "https://xxx.crm.dynamics.com"; string appId = "44fbace3-81ad-42f2-a76a-a7d377fec266"; string reDirectURI = "https://localhost"; string loginPrompt = "Auto"; string ConnectionString = string.Format("AuthType = {0};Username = {1};Password = {2}; Url = {3}; AppId={4}; RedirectUri={5};LoginPrompt={6}", authType, userName, password, url, appId, reDirectURI, loginPrompt); CrmServiceClient svc = new CrmServiceClient(ConnectionString); return svc; 

} 











public void PerformCRUD(CrmServiceClient svc)

{ //CREATE var myContact = new Entity("contact"); myContact.Attributes["lastname"] = "Learn"; myContact.Attributes["firstname"] = "Softchief"; myContact.Attributes["jobtitle"] = "Consultant"; Guid RecordID = svc.Create(myContact); Console.WriteLine("Contact create with ID - " + RecordID); //RETRIEVE Entity contact = svc.Retrieve("contact", new Guid("df4df113-746c-eb11-a812-000d3a3b1114"), new ColumnSet("firstname", "lastname")); Console.WriteLine("Contact lastname is - " + contact.Attributes["lastname"]); //Retrieve Multiple Record QueryExpression qe = new QueryExpression("contact"); qe.ColumnSet = new ColumnSet("firstname", "lastname"); EntityCollection ec = svc.RetrieveMultiple(qe); for (int i = 0; i < ec.Entities.Count; i++) { if (ec.Entities[i].Attributes.ContainsKey("firstname")) { Console.WriteLine(ec.Entities[i].Attributes["firstname"]); } } Console.WriteLine("Retrieved all Contacts..."); //UPDATE Entity entContact = new Entity("contact"); entContact.Id = RecordID; entContact.Attributes["lastname"] = "Facts"; svc.Update(entContact); Console.WriteLine("Contact lastname updated"); //DELETE svc.Delete("contact", RecordID); //Execute Entity acc = new Entity("account"); acc["name"] = "Soft"; var createRequest = new CreateRequest() { Target = acc }; svc.Execute(createRequest); //Execute Multiple var request = new ExecuteMultipleRequest() { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; Entity acc1 = new Entity("account"); acc1["name"] = "Soft1"; Entity acc2 = new Entity("account"); acc2["name"] = "Soft2"; var createRequest1 = new CreateRequest() { Target = acc1 }; var createRequest2 = new CreateRequest() { Target = acc2 }; request.Requests.Add(createRequest1); request.Requests.Add(createRequest2); var response = (ExecuteMultipleResponse)svc.Execute(request); }

Monday, 17 May 2021

User does not have the privilege to act on behalf another user error while using impersonation in Web API in Dynamics 365.

 {\r\n  \”error\”:{\r\n    \”code\”:\”\”,\”message\”:\”User does not have the privilege to act on behalf another user.\”,\”innererror\”:{\r\n      \”message\”:\”User does not have the privilege to act on behalf another user.\”,\”type\”:

Impersonation in Web API

http://www.inogic.com/blog/2016/02/impersonation-available-using-web-api-in-dynamics-crm-2016/

This error can occur in a scenario when User A is trying to impersonate User B, but user A doesn’t have “Act on Behalf of Another User” privilege.

Below article nicely explains it

https://community.dynamics.com/crm/b/magnetismsolutionscrmblog/archive/2013/07/18/act-on-behalf-of-another-user

Hope it helps..

Sample code to connect to CDS / Dynamics 365 / CE using OAuth

 Sample code for quick reference for connecting to CDS through a console application using OAuth

Add the NuGet package for Microsoft.CrmSdk.XrmTooling.CoreAssembly in the project.

Xrm.Tooling is the preferred way to connect to CDS, because of many benefits – we can define connection string, thread safety, support for X.509 certificate authentication, support for secure storage of sign-in credentials and reuse etc.

Note –

Here we will be using the sample AppId and Redirect URI.

Sample Code- 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;
using System;
 
namespace SampleConsoleApp
{
class Program
{
static void Main(string[] args)
{
string ConnectionString = "AuthType = OAuth; " +
"Username = [username]@[domain].onmicrosoft.com;" +
"Password = [password]; " +
"Url = https://[orgname].crm.dynamics.com;" +
"AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;" +
"RedirectUri=app://58145B91-0C36-4500-8554-080854F2AC97;" +
"LoginPrompt=Auto";
 
CrmServiceClient svc = new CrmServiceClient(ConnectionString);
 
if (svc.IsReady)
{
var myContact = new Entity("contact");
myContact.Attributes["lastname"] = "Test";
myContact.Attributes["firstname"] = "User1";
svc.Create(myContact);
}
}
}
}

For .NET Framework 4.5.2 – we need to explicitly specify Tls1.2 as the default protocol. 

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

.NET Framework 4.6.2 uses TLS 1.2 as the default protocol.

Introduction to Dynamics 365 CE Data Migration using ADF

Dynamics 365 CE Data Migration using ADF can be necessary for various reasons, such as archiving historical data, integrating with other sys...