Configure Session Timeout and Inactivity Timeout – Dynamics 365

In Dynamics 365, we can now define Session timeout and Inactivity timeout.

We need to go Settings à Administration à System Settings à General Tab

By default, the session timeout is set to 24 hours along with 20 minutes for warning the user.

We can set our custom values there.

Enter maximum session length 60 – 1440 minutes. ( 1 to 24 hour)
How long before the session expires do you want to show a timeout warning? 20 – 1440 minutes. Must be less than maximum session length.

We can also set the timeout based on inactivity. By default, this setting is not enabled. Below are the values that we can set for inactivity timeout.

Enable session timeout due to inactivity 5 – 1440 minutes. (5 minutes to 24 hours) – Must be less than the maximum session length.
How long before the session expires do you want to show an inactivity warning? Less than Session timeout due to inactivity

Session Timeout warning à

Session expired à

Inactivity warning à

Inactivity Session expiration à

More details.

https://docs.microsoft.com/en-in/dynamics365/customer-engagement/admin/user-session-management

Hope it helps..

Implementing “Does not contain data” for N – N relationships through RetrieveMultiple plugin in Dynamics 365

Recently we had a requirement to create a marketing list with members (contact) which are not part of any other marketing list through Advanced Find.

In version 9.0 we have “Does not contain data” filter added in Advanced Find. However, it works only in case of 1 – N relationship.

https://nishantrana.me/2017/10/19/does-not-contain-data-filter-in-advanced-find-in-dynamics-365-july-2017-update/

Here in our case, it is an N-N relationship between Contact and Marketing List.

The solution we implemented was following –

We asked the user to select the following condition in their Advanced Find query.

Which will have the following fetch XML à

And in our Retrieve Multiple Plugin, we added a new filter condition and replaced link entity condition as shown below for implementing the outer join.

Below is the sample code for the plugin that achieves this. The plugin is Registered on Pre Retrieve Multiple of Contact.

The code –


public class PreRetrieveMultipleML : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));

// Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Query") && context.InputParameters["Query"] is QueryExpression && context.MessageName == "RetrieveMultiple")
{
var query = (QueryExpression)context.InputParameters["Query"];

tracingService.Trace("Inside Plugin");

if (query != null && query.EntityName == "contact")
{
foreach (var linkedEntity in query.LinkEntities.Where(
a =>
a.LinkFromAttributeName.Equals("contactid") &&
a.LinkToAttributeName.Equals("entityid") && a.LinkToEntityName.Equals("listmember") &&
a.LinkEntities.Count == 1 && a.LinkEntities[0].LinkCriteria != null))
{
if (linkedEntity.LinkEntities[0].LinkCriteria.Conditions.Count == 1
&& linkedEntity.LinkEntities[0].LinkCriteria.Conditions[0].AttributeName.Equals("listid")
&& linkedEntity.LinkEntities[0].LinkCriteria.Conditions[0].Operator == ConditionOperator.Null)
{
// remove the existing link entity
query.LinkEntities.Remove(linkedEntity);

// create a new link entity
LinkEntity doesNotContainLinkEntity = new LinkEntity()
{
EntityAlias = "ml",
LinkFromEntityName = "contact",
LinkToEntityName = "listmember",
LinkFromAttributeName = "contactid",
LinkToAttributeName = "entityid",
JoinOperator = JoinOperator.LeftOuter
};

// add the newly created link entity
query.LinkEntities.Add(doesNotContainLinkEntity);

// create a new condition expression
var doesNotContainCondition = new ConditionExpression();
doesNotContainCondition.AttributeName = "listid";
doesNotContainCondition.Operator = ConditionOperator.Null;
doesNotContainCondition.EntityName = "ml";

//create a new filter condition
var doesNotContainFilterExpression = new FilterExpression();
doesNotContainFilterExpression.AddCondition(doesNotContainCondition);

// add this new filter in query
query.Criteria.AddFilter(doesNotContainFilterExpression);

break;
}
}
}
}
}
}

We can update the plugin’s code to be used for any other N-N relationship similarly.

Hope it helps..

“Register a New WebHook” through Plugin Registration Tool in Dynamics 365

With July 2017 Update, now we have the option to register a new Webhook through Plugin Registration tool.

Download the latest Plugin Registration Tool from NuGet using the PowerShell script à

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/download-tools-nuget

Through registering a Webhook, we can send data (execution context) about any operation performed on Dynamics 365 to the external services or application. The execution context information is passed in JSON format here.

More details here

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/use-webhooks

Let us take a simple scenario to see it in action.

First will create an Azure Webhook which passes the Execution Context to the Azure Service Bus Queue. We will also create a sample Queue Listener application that parses and reads the information from the queue.

  • Create a new Function of type Webhook + API (CSharp).

  • Select Integrate in the newly created function and click on New Output button and add Azure Service Bus as an output.

  • Specify Message type as Service Bus Queue and other required values like Service Bus Connection, Queue Name and the parameter name and click on Save.
  • Update the code for our function to pass the execution context information to the queue
  • Now let us register our Webhook inside Dynamics 365. For this copy the function URL using Get function URL button.


  • Click on Copy.

  • Inside Plugin Registration tool, click on Register à Register New Web Hook.

  • Specify any Name for the Webhook. In the Endpoint URL, paste the URL copied without any query string part. For Authentication select WebhookKey and paste the “code” query string value to register the Webhook.

  • Register a new step of Lead Create to it.

  • After registering the step, to test our Webhook Function, let us create a new lead record inside Dynamics 365.

  • Back in our function, click on Monitor to check the log. There we can see the execution context information passed to our function.

  • Inside the Queue specified as Output of the function, we can see the new messages added.

  • Below is the sample code to read the message from the queue.

private static void QueueClientExample()
{
// create a new Shared Access Policy for the queue
// set the connection string of the Shared Access Policy created
var connectionString = "Endpoint=sb://[namespace].servicebus.windows.net/;SharedAccessKeyName=MyPolicy;SharedAccessKey=[KeyValue];EntityPath=mycrmqueue";

// create the Queue Client object
var client = QueueClient.CreateFromConnectionString(connectionString);

// get the message from the Queue Client
BrokeredMessage brokeredMessage = client.Receive();

var stream = brokeredMessage.GetBody<Stream>();
StreamReader streamReader = new StreamReader(stream);
string jsonData = streamReader.ReadToEnd();
jsonData = jsonData.Replace(@"\", string.Empty).Trim(new char[] { '\"' });
JObject context = JObject.Parse(jsonData);

Console.WriteLine("Primary Entity Name = " + context["PrimaryEntityName"] + " Message Name = " + context["MessageName"]);

}

  • The output

More on Azure Functions à

https://nishantrana.me/category/azure-functions/

Similar example using Azure Service Bus Integration à

https://nishantrana.me/2017/03/22/configure-dynamics-365-and-azure-service-bus-integration-through-queue-and-queueclient/

Hope it helps..

“Invalid Argument” Error while setting properties in SLA

Ajit Patra

Recently, we were working on SLA. We provided necessary conditions in Applicable When and Success Criteria sections. In Success Actions section, we wanted to update Customer Record(OOB entity “contact” renamed) and clicked on Set properties as shown below:

SetProperties

On click of it, we got “Invalid Argument” error as shown:

Invalid_Error

To fix this issue, we copied the URL of this window and decoded it. We got the root cause of this issue by looking at the decoded URL. The decoded URL contained the following piece of information:

Error Details: Wrong type of attribute UI properties passed to the attribute “custom_field”.&RequestUri=/SFA/Workflow/entityform.aspx?entityFullName=contact.regardingobjectid&entityname=contact&mode=1&primaryentity=task&readonlymode=true&relatedattributename=regardingobjectid&stepId=UpdateStep30&workflowId=712b088a-9dc1-4b3a-acc2-a1e8e8ebcacf&user_lcid=1033

We found that one of the custom field(“custom_field”) we had created was causing this issue. This field was put on the form.

We understood the problem. We had created a field with same schema name earlier with “Single Line of Text” type and later we realized that the field should have…

View original post 71 more words

Sample Code for Autonumbering in Dynamics 365 July 2017 Update

As a first step, add references to the latest version 9 assemblies

https://www.nuget.org/packages/Microsoft.CrmSdk.CoreAssemblies/

In the below sample code, we are creating an Auto number attribute in Contact Entity.

This is how the fields shows up inside contact form.

Using UpdateAttribute Request we can update the format for the AutoNumber field.

And also, we can have multiple auto number fields for an entity as shown below.

Sample Code


CreateAttributeRequest createAttributeRequest = new CreateAttributeRequest();
createAttributeRequest.EntityName = "contact";

var autoNumberAttributeMetadata = new StringAttributeMetadata()
{
AutoNumberFormat = "Auto Number - {SEQNUM:4} - {RANDSTRING:4} - {DATETIMEUTC:yyyyMMddhhmmss}",
SchemaName = "new_autonumber1",
MaxLength = 100,
RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.ApplicationRequired),
DisplayName = new Microsoft.Xrm.Sdk.Label("My Auto Number", 1033),
Description = new Microsoft.Xrm.Sdk.Label("This is my first auto number field through SDK", 1033)
};

createAttributeRequest.Attribute = autoNumberAttributeMetadata;
var response = organizationService.Execute(createAttributeRequest);

And now the simplest and best way to create these Auto Number fields à

Using Auto Number Manager developed by Jonas Rapp, Microsoft MVP.

https://www.linkedin.com/pulse/auto-number-attributes-microsoft-dynamics-365-jonas-rapp/

https://www.xrmtoolbox.com/

https://github.com/MscrmTools/XrmToolBox

Hope it helps..