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.

Git Basic working

  Develop = dev   r