Pro-grammatically create Document location records in SharePoint Online from Dynamics Customer Engagement Online without using native integration

Hi Folks,

Have you ever got a requirement to specifically create records in SharePoint without using the out of the box CRM-Sharepoint integration, then your were at right place and this post is going  absolutely help you with your requirement.

With the out of box integration, we will be able to create records in SharePoint when we navigate to OPEN LOCATION under Document Associated grid. But this adds record GUID to name of the record being created. But in our case, we only want the document location record to be created  with the name of the record. Please use the below code…all you need is Tenant ID, Resource ID, Client ID, Client Secret and your SharePoint domain and URL.

This approach uses Access token approach using the SharePoint based Add-in.

Steps to create SharePoint based Add-in. Navigate to below URL…

Ex: [Site Collection URL]/_layouts/15/AppRegNew.aspx0

AppRegNew Form

At this point, you’ll need to fill in the following details,

Name Description
Client Id Click Generate unique client id for your add-in. It’s a GUID which will be used to identify your add-in.
Client Secret Acts like a password for your add-in. It will include some special characters as well. So while using it, we have to encode the same first.
Title The name of your add-in that will be displayed to the end user.
App Domain For provider-hosted add-in, this will be the domain where, the add-in is hosted. For token generation add-in, fill in any value. Make sure, not to include protocols(https) or slashes(/).
Redirect URI For provider-hosted add-in, fill in the redirect URL. For token generation add-in, fill in any value.

Once you have filled in all the below details, hit Create to register the add-in1

Register SharePoint Add-in

    • You will be navigated to a page displaying the details of your add-in. Save Client Id & Client Secret for future references(Don’t forget this step as you won’t be able to navigate to this page to view details later)2                                  SharePoint Add-in Identifier
    • Grant permission to an add-in

      Now that the identifier is created, we need to grant the necessary permission for it to perform any action. In this example, I’ll demonstrate how to grant full control access on a Site Collection.

      • Navigate to
        [Site Collection URL]/_layouts/15/AppInv.aspx

        3

      • Enter your Client Id value in the App Id option and hit the Lookup button. Details of your add-in will be displayed automatically.4
      • Now this is crucial, you need to give permissions to your app. In the option, Permission Request XML, let’s write the below XML code to grant our add-in full control on the given site collection.Capture
      • Just hit the Create button. You will now be prompted to trust the add-in for all the permissions that it requires.5                                      Trust SharePoint Add-In
      • Hit the Trust It to grant the requested accesses. You can navigate to the following URL to also confirm that the permission has been assigned to the add-in.
        [Site Collection URL]/_layouts/15/appprincipals.aspx

        6

    • Now once you have created the app in SharePoint, you need to get the access token to perform CRUD Operations in SharePoint using REST API.
    • For testing purpose, you can use either POSTMAN or a console application…I have written the approach in both the ways.
    • For retrieving Tenant ID firstly using postman..
    • Perform a GET Request to the following URL..
    • [Site Collection URL]/_vti_bin/client.svc
    • After entering the above URL in the text-box in the URL text-box. We will get the Unauthorized exception on accessing the information. Because SharePoint Online is very much secured and that doesn’t allow anonymous users to access the information for their site. The below is the error message response, after sending the request. Highlighted is your Tenant ID..note it down..Capture1
    • Instead you can use the below C# code to get the Tenant ID details:public string GetTenant(string stGetTenantDetailsUrl)
      {
      WebRequest myWebRequest;
      string tenantID = string.Empty;
      string resourceID = string.Empty;
      string accessToken = string.Empty;myWebRequest = WebRequest.Create(stGetTenantDetailsUrl);
      myWebRequest.Method = “GET”;
      myWebRequest.Headers.Add(“Authorization”, “Bearer”);
      WebResponse myWebResponse = null; ;
      try
      {
      myWebResponse = myWebRequest.GetResponse();
      return tenantID;
      }
      catch (System.Net.WebException ex)
      {
      //get the Web exception and read the headersstring[] headerAuthenticateValue = ex.Response.Headers.GetValues(“WWW-Authenticate”);
      if (headerAuthenticateValue != null)
      {foreach (string stHeader in headerAuthenticateValue)
      {
      string[] stArrHeaders = stHeader.Split(‘,’);
      //loop all the key value pair of WWW-Authenticate
      foreach (string stValues in stArrHeaders)
      {if (stValues.StartsWith(“Bearer realm=”))
      {
      tenantID = stValues.Substring(14);
      tenantID = tenantID.Substring(0, tenantID.Length – 1);
      }
      if (stValues.StartsWith(“client_id=”))
      {
      //this value is consider as resourceid which is required for getting the access token
      resourceID = stValues.Substring(11);
      resourceID = resourceID.Substring(0, resourceID.Length – 1);
      }
      }}

      }

      return tenantID;//your tenant ID
      }
      }

    • Next step is to get the Access token..from Postman..

                                         Generate the Access Token

      In response header, we will get WWW-Authenticate as one of the header and that contains the necessary information required for next step. The realm value contains the tenant id for the SharePoint Online site and clientid value contains the resource information (we’ll use it later).

      Key Syntax Value
      Content-Type application/x-www-form-urlencoded application/x-www-form-urlencoded

      Body

      Key Syntax Value
      grant_type client_credentials client_credentials
      client_id ClientID@TenantID 4b4276d0-74cd-4476-b66f-e7e326e2cb93@10267809-adcb-42b6-b103-c7c8190b3fed
      client_secret ClientSecret nuC+ygmhpadH93TqJdte++C37SUchZVK4a5xT9XtVBU=
      resource resource/SiteDomain@TenantID 00000003-0000-0ff1-ce00-000000000000/spsnips.sharepoint.com@10267809-adcb-42b6-b103-c7c8190b3fed
      • After applying the configuration, click Send button. That will returns the response with the Access Token.

      Fig 7: Postman response contains Access Token

      You can use the below C# code to generate access token

      public string GetAuthorisationToken(string stGetAccessTokenUrl, string stSiteDomain, string tenantID, string resourceID, string stClientID, string stClientSecret)
      {

      string accessToken = string.Empty;
      stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);

      WebRequest request = WebRequest.Create(stGetAccessTokenUrl);

      request.ContentType = “application/x-www-form-urlencoded”;
      request.Method = “POST”;

      string postData = “grant_type = client_credentials” +
      “&client_id =” + WebUtility.UrlEncode(stClientID + “@” + tenantID) +
      “&client_secret =” + WebUtility.UrlEncode(stClientSecret) +
      “&resource =” + WebUtility.UrlEncode(resourceID + “/” + stSiteDomain + “@” + tenantID);

      byte[] byteArray = Encoding.UTF8.GetBytes(postData);
      // Set the ContentType property of the WebRequest.
      request.ContentType = “application/x-www-form-urlencoded”;
      // Set the ContentLength property of the WebRequest.
      request.ContentLength = byteArray.Length;
      // Get the request stream.
      Stream dataStream = request.GetRequestStream();
      // Write the data to the request stream.
      dataStream.Write(byteArray, 0, byteArray.Length);
      // Close the Stream object.
      dataStream.Close();

      try
      {
      using (WebResponse response = request.GetResponse())
      {
      dataStream = response.GetResponseStream();
      // Open the stream using a StreamReader for easy access.
      StreamReader reader = new StreamReader(dataStream);
      // Read the content.
      string responseFromServer = reader.ReadToEnd();
      // Clean up the streams.
      reader.Close();
      dataStream.Close();
      //Get accesss token
      accessToken = “access_token\”:\””;
      int clientIndex = responseFromServer.IndexOf(accessToken, StringComparison.Ordinal);
      int accessTokenIndex = clientIndex + accessToken.Length;
      accessToken = responseFromServer.Substring(accessTokenIndex, (responseFromServer.Length – accessTokenIndex – 2));

      return accessToken;

      }
      }
      catch (WebException wex)
      {
      HttpWebResponse httpResponse = wex.Response as HttpWebResponse;
      createlog(_service, “Error occured” + wex.ToString());
      throw new InvalidPluginExecutionException(“Exception occured while retrieving Access Token” + wex.ToString());

      }

      }

      Once we are received the access token, you were all set and we got the authorization to access the SharePoint data based on the permission applied in Grant Permission of Add-In .

      So now we would implement our logic to create folders in plugin…make sure we should be passing the Access token received while accessing share point.

      public void CreateFolder(string sharePointSite, string token, string library, string folder,Guid entityID)
      {
      string result = string.Empty;
      StringBuilder sb = new StringBuilder();
      sb.Append(sharePointSite);
      sb.Append(“_api/web/GetFolderByServerRelativePath(decodedUrl='”);
      sb.Append(library);
      sb.Append(“‘)/Folders”);
      Uri uri = new Uri(sb.ToString().Replace(“{“, “”).Replace(“}”, “”));
      HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(uri);
      wreq.Headers.Add(“Authorization”, “Bearer ” + token);
      wreq.Method = “POST”;
      wreq.ContentType = “application/json”;
      string postData = “{‘ServerRelativeUrl’:’folder’}”;
      postData = postData.Replace(“folder”, folder);
      byte[] byteArray = Encoding.UTF8.GetBytes(postData);
      wreq.ContentLength = postData.Length;
      Stream dataStream = wreq.GetRequestStream();
      dataStream.Write(byteArray, 0, byteArray.Length);
      dataStream.Close();
      WebResponse wresp = null;
      try
      {
      wresp = wreq.GetResponse();
      using (wresp = wreq.GetResponse())
      {
      dataStream = wresp.GetResponseStream();
      StreamReader reader = new StreamReader(dataStream);
      string responseFromServer = reader.ReadToEnd();
      reader.Close();
      }
      }
      catch (WebException wex)
      {
      HttpWebResponse httpResponse = wex.Response as HttpWebResponse;
      createlog(_service, “Error occured” + wex.ToString());
      throw new InvalidPluginExecutionException(“Exception occured while creating record” + wex.ToString());
      }
      }

  • You can place the Client ID, Client Secret, Sharepoint domain name in Unsecure configuration in Plugin for easier movement of code to other environment.
  • Entire code is available here…you can grab it…
  • Hope this helps some one looking out integrating Dynamics CRM Online with SharePoint online without relying on out of box integration between Dynamics CRM & SharePoint.
  • Hope you enjoyed this post…please post your valuable comments..

Cheers,

PMDY

Advertisement

Author: Pavan Mani Deep Y

Technology geek who loves sharing my leanings, quick tips and new features on Dynamics 365 & related tools, technologies. An Azure IOT Enthusiast....

2 thoughts on “Pro-grammatically create Document location records in SharePoint Online from Dynamics Customer Engagement Online without using native integration”

  1. Hi Pavan,
    Can I get the unsecureConfig file from which the contents are read? That will be helpful please. Or you can just send me the file on my mail id please. Struggling since last week. My mail id: emailatprashant@gmail
    Thank you very much for the explanation !!!
    -Prashant V

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

ECELLORS CRM Blog

Sharing thoughts and challenges on Power Platform & Azure along with respective solutions put together...

SharePains by Microsoft MVP Pieter Veenstra

Microsoft 365, Power Platform, SharePoint, Teams, Azure and Dynamics

D365 Demystified

A closer look at Microsoft Dynamics 365.

Vicky Rodgers - Microsoft Dynamics 365

Everything Microsoft Dynamics 365 for Customer Engagement

XRM Tricks (Power Platform & Dynamics CRM )

Power Platform & Dynamics CRM

Microsoft Dynamics 365 UK MCT

All about Microsoft Dynamics 365

High Voltages

Arduino | ESP | Raspberry pi | IoT

Mihail's space

Just another WordPress.com site

Arun Potti's MS CRM blog

Microsoft Dynamics CRM

Sander van de Velde

Microsoft MVP Azure | IoT Platform Architect | Speaker about IoT | Let me add some value

Power Platform Blog

Author : Dharanidharan Balasubramaniam

That API Guy

Making the world a better place one PowerApp/Flow at a time!

Dynamics Back Page

Tips, Tricks, and General Musings on Dynamics 365 (CRM), the Power Platform, Power Apps, Power Automate, Power BI and related technologies

Azure Integration services for Dynamics 365

Azure Integration services for Dynamics 365 Unified Operations, Logic Apps, Azure Functions, REST

Power Maverick

Incredible journey into #Dynamics365, #CDS, #PowerApps #Azure and all good stuff that #Microsoft releases

Unleashing CRM

My Technical Thoughts about Microsoft Dynamics CRM- Unleashed

Srikanth Alluri

My experiences in & around Power Platform + Azure

Debajit's Power Apps & Dynamics 365 Blog

All about Power Apps & Dynamics

Rajeev Pentyala - Microsoft Power Platform

Sharing my knowledge on Power Platform, Dynamics 365, Azure & .Net Stack

Bansal Blogs - Dynamics 365, PowerApps, Microsoft Flows, Power BI

Programming demands a lot more than simple mastery in tools and technologies

%d bloggers like this: