Using tpc.identity to get the logged in user details in JavaScript in The Portal Connector (TPC)

Recently while working in TPC, we had a requirement to get the details of the logged in user (which is basically a contact record in CRM).

To do so we can make use tpc.identity object in Client Side.

For e.g. contactId

Hope it helps..

Missing Price for Products in The Portal Connector – E Commerce Settings – Dynamics CRM.

Recently we configured products from CRM to e-commerce setting of The Portal Connector and found that the price for the product was missing.

The way to fix this issue is to Open the product form in CRM and add the list price field on the product form and specify the value there.

Once value is specified, go to administration – portal connector configuration and click on Resynchronize to update the product record in the portal.

Once synchronization is done, we can see the values updated in the portal.

Hope it helps..

Configuring CRM Form inside The Portal Connector for Dynamics CRM / Dynamics 365

The Portal Connector makes it easy to quickly setup a portal that interacts with CRM.

Here let us look at a simple example of setting up Lead form in Insert Mode, which creates lead record in CRM.

Open the Dashboard

Go to CRM Entities and click on Create a CRM Entity.

Here we are creating Lead entity.

Once our lead is setup, we’d create the form.

Go to Contents – Forms.

Click on Create a form.

Inside form, first go to Layout and select TPC Form Layout.

Then go to Content tab, and add Form Configuration

Click on Edit inside Form Configuration and specify the Lead entity we just created.

Drag and add two text fields, one we will configure against first name and other with last name.

Do the same for Last Name text box and publish the form.

Next we need to create a Page wherein we’d display this form. Go to Pages and click on Create a page.

We have created a page named Lead.

Drag TPC Form Manager in the page content.

Configure it and specify our newly created My Lead form.

Select Insert Only check box.

Publish the page and test it. Specify the values and click on Submit.

We’d get the following message.

The lead record created in CRM.

Hope it helps..

Fixed – Workflow must be in Published State error while converting Case to Work Order in CRM

Recently, while trying to convert a case to work order we got the below error.

The immediate thought was to check all the workflow associated to work order and case and see if they all are published, which in fact they were.

Then as suggested here

http://ms-crm-2011-beta.blogspot.ae/2016/11/workflow-must-be-in-published-state.html

we deactivated and activated one of our SLA written against the Work Order entity and it fixed the issue.

Hope it helps..

Sample code to upload file to Azure Blob Storage from CRM Online Plugin

Sharing a sample code which we can use to upload files to Azure Blog Storage from within a CRM Online Plugin. Here we’d be making use of the REST API to simplify things (instead of using Windows Azure Storage library) in our Plugin.

First, we will be creating a storage account of type blob storage and a container inside it.

Log in to Azure Portal

https://portal.azure.com

Click on Add to add a new storage account.



Create a new container in it to store the blob files



In Azure Portal – Storage Account, go to Access Keys and copy the key


And also note down the storage account name and container name which will be used to construct the URL.


We can also go to container, select its properties and copy the url.


Here we have written the plugin on Create of Annotation, which then retrieves the attachment and uploads its content to the container.

Let us first see it in action.

We have created a new note and attached a text file to it.


Going back to our portal, we can see the file in our container.


The sample code for the plugin.

using Microsoft.Xrm.Sdk;
using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
namespace MyTestPlugin
{

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

// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity noteEntity = (Entity)context.InputParameters["Target"];
byte[] doumentBody = Convert.FromBase64String(noteEntity.Attributes["documentbody"].ToString());
string content = Encoding.UTF8.GetString(doumentBody);
string fileName = noteEntity.Attributes["filename"].ToString();

// Upload the attached text file to Azure Blog Container
UploadFileToAzureBlobStorage(content, fileName);

}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message);
}
}

void UploadFileToAzureBlobStorage(string content, string fileName)
{

string storageKey = "storagekey";
string storageAccount = "storageaccountname";
string containerName = "strogaecontaninername";
string blobName = fileName;

string method = "PUT";
string sampleContent = content;
int contentLength = Encoding.UTF8.GetByteCount(sampleContent);

string requestUri = $"https://{storageAccount}.blob.core.windows.net/{containerName}/{blobName}";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);

string now = DateTime.UtcNow.ToString("R");

request.Method = method;
request.ContentType = "text/plain; charset=UTF-8";
request.ContentLength = contentLength;

request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, containerName, blobName));

using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
}

using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
if(resp.StatusCode == HttpStatusCode.OK)
{
// successfully uploaded
}
}

}

public string AuthorizationHeader(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName, string blobName)
{
string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:{now}\nx-ms-version:2015-12-11";
string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{headerResource}\n{urlResource}";

HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
return AuthorizationHeader;
}
}

}

Hope it helps.

Using Azure Functions for writing Scheduled Jobs for Dynamics CRM

In our previous post we saw how we can invoke CRM from within the Azure Function.

https://nishantrana.me/2017/04/28/call-dynamics-crm-from-azure-functions/

Using that knowledge, let us now write an Azure Function that will run periodically.

Here we will take a simple example of creating a lead record every 2 minutes. Obviously real world scenario would involve much complex scenario like checking the status of all the open records and update them daily something of that sort.

Another way of writing a scheduled job is using Web Job I have written about it over here.

https://nishantrana.me/2017/03/21/dynamics-crm-web-job-and-azure-scheduler/

Login to Azure Portal and create a new Function App

Create a new function with Timer and CSharp template.

function.json bindings defines the schedule for the timer, it take a CRON expression for value schedule.

CRON Expression format: –

If we want it to run every 2 minute

Back to our code let us click on Run and test it.

Now let us quickly plumb the code to create Lead in CRM.

Go to App Service Editor for the Function App and add new a file named project.json which refers to the CRM Nuget Package.

Sample code that creates the lead record in CRM.




using System.Net;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;

public static void Run(TimerInfo myTimer, TraceWriter log)
{
IServiceManagement<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri("https://nishutrial.crm.dynamics.com/XRMServices/2011/Organization.svc"));

AuthenticationCredentials authCredentials = new AuthenticationCredentials();
authCredentials.ClientCredentials.UserName.UserName = "test@test.onmicrosoft.com";
authCredentials.ClientCredentials.UserName.Password = "*******";
AuthenticationCredentials tokenCredentials = orgServiceManagement.Authenticate(authCredentials);

OrganizationServiceProxy organizationProxy = new OrganizationServiceProxy(orgServiceManagement, tokenCredentials.SecurityTokenResponse);
Entity lead = new Entity("lead");
lead.Attributes["subject"] = "Lead Created at" + DateTime.Now ;
organizationProxy.Create(lead);

log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
}

Inside CRM

To monitor our Azure Function please select Monitor

Click on live event stream to monitor it real-time.

To stop or disable the function, select Manage and click on function state Disabled.

Hope it helps..