Custom integration between Dynamics 365/CDS and SharePoint using C# and SharePoint REST API ? Learn how to create a SharePoint Add-in and generate authentication token–Part 3

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

If you are directly on this blog post, I suggest you start from the first blog post of this series to get the context.

So I am on the final blog of this series. And here I am going to generate the authentication token to finally connect to SharePoint. Here we will deal with two most important properties of the Add-in, Add-In ID and Add-In Secret. Using these two properties now we will construct the access token.

Let us achieve this in the following steps

  • Open your VS and create a Console Application. ( I am using VS 2017 and created a console application with .Net framework 4.6.2)

  • After your project is created we need to add the SharePoint Dependencies. To do this right click on References and Manage NuGet packages and look for a package named AppForSharePointOnlineWebToolkit and install the package.

While trying to add the reference you may face an issue saying Microsoft.IdentityModel.dll was not found so package could not be installed.

If that’s the case, add Microsoft.IdentityModel.dll using NuGet package.

  • Post doing step 3 as well you will not be able to reference SharePoint Dependencies since it again looks for another dll named Microsoft.IdentityModel.Extensions dll.
  • Include the reference for Microsoft.IdentityModel.Extensions.dll

  • Now let us try to install the package named AppForSharePointOnlineWebToolkit. Not only this package will add the SharePoint Dependencies but also includes the class files TokenHelper.cs and SharePointContext.cs
  • Now we have included all the dependencies required for the operation. Make sure to include the below configuration in App.config file
  • Use the Client ID and Client Secret of the Add-In and replace its values in App.Config file. This is because TokenHelper.cs class will grab the id and secret from the application’s configuration file. Add the following piece of code in your application to generate the token.
string siteUrl = "https://xrm20208.sharepoint.com";

//Get the realm for the URL

string realm = TokenHelper.GetRealmFromTargetUrl(new Uri(siteUrl));

//Get the access token for the URL.  

string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, new Uri(siteUrl).Authority, realm).AccessToken;

  • As you can see in the below screenshot my token is generated successfully.

Yahoo! Now that is some relief right? The token is now generated and you can passing it as a bearer token while making any calls to SharePoint REST API. I am not going to show you how you are now going to consume the REST API. We have innumerable good SharePoint blogs for the same. So I leave the remaining part for you to explore.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Skip Setting a Business process flow during record create in Dynamics 365/ CDS? This simple trick may help you

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

We all love Business Process flows. And why not? Their introduction have solved the age old problem of visualizing a record as and when it progress through multiple stages. Typically lead and opportunity moving through multiple stages, a product moving through multiple stages of development and numerous other examples can be cited.

And yet there can be scenarios where you need to skip applying business process when the record is created. Typical example may be bulk importing records from some other sources where you are not sure about what business process need to be applied and you want the decision to be left to end-users when they work with the respective records. Really there can be scenarios which you never thought.

I've never thought about it like that before | Honest about my faith

In scenarios like this, how do you plan to do the same. After all the default business process flow configured for an entity is automatically applied when you create new record for the entity.

We know for every entity there is a field called ProcessId. You may be wondering, isn’t it deprecated. Yes it is deprecated. However as much surprising it is, the same will come to help in scenarios like this.

All we need to do in this case is set the ProcessId field to Guid.Empty. That’s all.

And how are you going to do it. Well there can be many ways but in our scenario if it is bulk import, we can have a plugin in pre-operation stage where we will set the value of ProcessId to Guid.Empty.

Something like this shall work.

public class SetProcessIdToBlank : IPlugin
    {
       public void Execute(IServiceProvider serviceProvider)
       {
          var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
          var target = (Entity)context.InputParameters["Target"];

         target["processid"] = Guid.Empty;
       }
    }

And now the records shall be created without any Business process flow record.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Stop Assign functionality based on Business Logic using Client API in Dynamics 365

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

Assign – an age old functionality which is there since the time I started working in CRM which dates way back to 2011. So much we have seen about Assign that whenever I talk about Assign it’s like going back to our school days. But sometimes stuff from our school days we miss out which can be quite interesting when we discover it in our later years.

So here was this requirement. When a user clicks on the Assign and try to assign a record to a user or team, there should be some custom business validations based on which we will decide whether to go ahead with the Assign. If not then we will throw a custom message to the user.

So let’s see the tried and tested options and see why they won’t fit here.

Writing a plugin

For me it’s the best solution because it handles server side scenarios as well. However while the plugin shall still be there, the error dialog throw from plugins is not acceptable by the end-users here. They want more of like an alert dialog available in Dynamics 365.

Show hide the Assign button using enable rules

While this works, it is absolutely essential for this validation to be as real time as possible. Also the customer wanted that the end-user should understand why he/ she is not able to assign the record and then take corrective action.

So what’s the other way? We all know that when Assign operation is performed, the record is saved and any save event you have registered fires as well. And here is secret. There is a specific save code for Assign which is 47.

Using the specific save code we can understand whether Assign is currently being executed by the user and take necessary action.

function record_onsave(e) {
    var saveMode = e.getEventArgs().getSaveMode();

   if (saveMode === 47) { // assign
       // perform your custom logic here
       // and show alert using Xrm.Navigation.openAlertDialog if assign is invalid.

      // also you can stop the save using code below.
       e.getEventArgs().preventDefault();
    }
}

Using this simple trick you can actually handle your assign event. One very important point to note here. If you expose the owner field on the form and the end-user updates the owner field, that is not considered as Assign operation and would be treated as regular save (savemode = 1). So your above code shall fail.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Configure conflict detection for mobile offline synchronization in Dynamics 365

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

In my previous article, I described in detail about Mobile Offline filters. Unlike the previous blog, this one is going to be real short. In this blog I am just going to discuss about a setting for conflict resolution when you have enabled Mobile Offline synchronization for your organization.

If you navigate to Advanced settings –> Mobile Offline, you will find an option – “Mobile Offline Settings”.

Once you click it, it basically opens the System settings –> Mobile client tab. There your have the below option.

image

By default, the value is set to No. So what is this conflict all about? When there is a mismatch of data between client and server, conflict errors occur.This setting help in resolution of these conflicts.

Suppose the user made some changes in offline mode and in the meantime the record has been modified on the server as well. If you set this value as No, the client wins over the server and whenever you go online, the changes made offline shall be synced. Client wins over the server.

If this setting is set to Yes, the server wins over the client and the offline changes are discarded if simultaneously the record the record has been changed on server as well.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Configuring Mobile Offline profiles in Dynamics 365 for Offline Sync on mobile devices

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

Trust me we all know about the offline feature of Dynamics 365 Mobile App. And if you ask even experienced Dynamics consultants on how to enable an entity for offline, the answer you get is you need to open the entity customizations and enable the below options.

image

In organization data download filter, you can define the filter criteria for data sync in mobile offline. So for the below filter, only accounts which are active and created in last 20 days shall be downloaded and available for mobile offline.

image

Till this point, almost everyone is aware. What is missed out is the Mobile Offline Profiles. Surprisingly it’s so much less discussed that many are not aware of it. But the fact remains that you need to create mobile offline profiles for users to configure filters that determine how much of an entity’s data (and related entities’ data) will be available to the user while offline.

So let’s see, how you can accomplish the same.

Go to Advanced Settings –> Mobile Offline

image

You may already find some profiles there but let’s start with a simple profile.

I enter a name for the profile – “Sample Offline Profile” and save the record. Here I will only show for account record. However you should do the following steps for all the entities which you want to enable for mobile offline sync.

Click on plus icon in “Mobile Offline Profile Item Details” to create a new Mobile Offline Profile item.

image

Observe I am using “All Records” as option here for data which will be downloaded. However one very important point here – The actual data available for mobile offline sync shall be the intersection of the filters specified in Offline Profile + Filter in organization data filter. If you remember the screenshot above, we have specified the filter there as active accounts created in last 2o days. Hence that shall be respected.

image

You have other options like “Other data filter” and “Custom data filter” using which you can specify custom filter rules.

I save the record. Now the “Mobile Item Profile Offline Association Details” grid becomes activated. In this grid, you can define the related data for account which can be enabled for mobile offline. For example, you want to download the active contact records for each account, we can define that using the below configuration.

image

You can create additional filters on the related records as well.

So we are all set for Account Entity here.

Now the final step is to assign users to this Offline profile. You can add users using the Users grid on the right.

The user “Chandana” is added to the profile. Please note that a user can be added to only one mobile offline profile.

image

And before I end, you remember the Organization data filters that you configured using the entity customization screen. Well, the same is present on the “Mobile Offline Profile Item” record for Account Entity that we just configured.

You can manage the same from here as well. Please note that to remove an entity from Mobile offline capabilities, you need to remove them from Mobile Offline filters where it is being referred.

image

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Base64 encoding and Base64 decode using Liquid in Dynamics 365/ PowerApps portals

For training and consulting, write to us at info@xrmforyou.com
Follow my blog for more interesting topics on Dynamics 365 and Portals

As I have been working on liquids a lot lately, I am amazed by the simple and yet powerful language which allows me to do so much without drop of a sweat. And then came this requirement.

Advertisements

I have to base64 encode and decode using Liquid. After having explored liquid so much, this was kind of stuff I never tried before in liquid. I thought after all with the kind of operators available in liquid, this would be a cakewalk. There must be a filter out there which allows me to do the same. Did a bit of search and surprisingly found nothing. But I was not ready to give up though.

So I started trying these constructs –

This is my base64 encoded string : {{ “abcde” | base64_encode }}

This is my base64 decoded string: {{ “YWJjZGVk” | base64_decode }}

image

Nothing worked out! I did find some references of bas64_encode and base64_decode filters in some liquid implementations but unfortunately they doesn’t work in portals.

But I have to meet the requirement. What should I do? It’s turn for me now to fall back to the good old JavaScript to do the same.

Advertisements

So I used the javascript btoa function for base64 encoding and atob function for base64 decoding.

Sample code below for reference.

{% assign account = entities.account[‘<accountid>’] %};

<div class="jumbotron" id="div_base64">

<script>

document.write(btoa("{{ account.crb08_encodefield }}")); // crb08_encodedfield is field in account entity

</script>

</div>

Advertisements

Similarly you can use atob function for decoding.

And that is where liquid failed me. Don’t worry liquid, you are still my dear friend.

image

Hope this helps!

For more interesting topics like this, follow my blog using follow button on top left of page. It’s all about Dynamics 365 and Portals.

Debajit Dutta

(Business Solutions MVP)