Saturday, December 17, 2016

Quick Tip - Turn Activity Feed Posts Off in Dynamics

Sometimes your clients not interested in using the Activity Feed Posts functionality in Dynamics. You can turn it off system wide in two simple steps. Firstly go to Settings -> Activity Feeds Configuration and filter all the Active records and Deactivate them.


Now goto Customization -> Default Solution and Publish all Customizations. You could do it for each entity if you prefer.


Once you refresh your browser cache the Posts tab on the activity pane will be hidden.





Monday, October 17, 2016

Message Listener with No Code Json Parsing

In this post I am going to show how you can configure a message listener in Dynamics CRM that will receive Json messages, parse the Json and create a record using the parsed data We are going to do all of this without any custom code.

First a bit of background on an unused corner of Dynamics CRM. Every activity record has a field called Additional Parameters which is designed to hold a Json payload. This is used by apps like Microsoft Social Engagement to automatically create CRM records from social media posts. The Json in the Additional Parameters field can be parsed and extracted by the record creation Rules.

We are going to create a record creation rule to create a contact record when an email is received by a queue and the rule will parse the Additional Parameter's Json and use the Json data to populate the contact fields. By using an email queue as our message transport mechanism we have ready made message listener. Details on how to create an email queue with an Office 365 shared mailbox here


Saturday, September 10, 2016

Simple Dynamics CRM Console Application

This is a quick tip on how to create a simple console application in C# that connects to Dynamics CRM 2016 and creates an account record. There is some sample  code in the SDK that demonstrates how to do this but this sample is even simpler.

static void Main(string[] args)
{
    // Get the CRM connection string and connect to the CRM Organization
    CrmServiceClient crmConn = new CrmServiceClient(ConfigurationManager.ConnectionStrings["CRM"].ConnectionString);
    IOrganizationService crmService = crmConn.OrganizationServiceProxy;
 
    Entity acc = new Entity("account");
    acc["name"] = "Joe's New Account";
    crmService.Create(acc);
                
}

Firstly create a new console application in Visual Studio and then go to the NuGet Package Manager option and install the Microsoft Dynamics CRM 2016 SDK Xrm Tooling Package.


Edit the app.config file in your project and add a connectionsStrings section with your CRM connection string.

  <connectionStrings>
    <add name="CRM" connectionString="AuthType=Office365;Url=https://joegilltest.crm4.dynamics.com; Username=joe@joegilltest.onmicrosoft.com; Password=MyPassword" />
  </connectionStrings>


Now add a reference to the System.Configuration assembly in your project so you can access your config file from code.



Add the following namespaces to your code

using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;

Now add the code shown at the top to your main method. When you run your console application it will connection to CRM and create an account record.






Friday, August 05, 2016

How to add an Editable Grid to a Dynamics CRM Form

A frequent request from users of Dynamics CRM is how can I edit records in a grid. This is not possible out of the box and users find it frustrating to edit records one by one. You could use the immersive Excel feature but this is limited in controlling which fields you can update as I wrote about previously. Also it is not real time and kicks off an import job so again the user experience could be better.

There are commercial editable grids available for Dynamics CRM however in this post I can going to show you can easily create an editable grid using D CRM Editable Grid which is free to use.


Monday, August 01, 2016

How to handle Nulls in Dynamics CRM Calculated Fields

One of the little wrinkles with calculated fields is that they cannot handle nulls and so if one of the values in the calculation is null then the calculated field value is null. 

Tuesday, July 26, 2016

Dynamics CRM - Google Charts Mashup

The combination of HTML Web Resources, Web API and Javascript libraries in Dynamics CRM allows you extensively customize the user interface. Here I am going to show how you can create a mashup of these technologies to show a custom appointments timeline chart on the account form. The out of the box charts are somewhat limited In Dynamics CRM however Google Charts has a vast array of charts which are free to use so I will use their timeline chart for this demo.




To accomplish this I created a HTML web resource which I added to the account form. Once it loads it runs JavaScript that does the following
  • Get the ID of the current account record
  • Web API call to get the appointments that reference the account id
  • Populate the Google Chart datatable with the Json returned
  • Call the Draw method to Render the chart
    The code is below  and you can see it references the Goggle Charts JavaScript libraries.

Sunday, July 17, 2016

Open Dynamics CRM Form Using Alternative Key

The introduction of alternative keys in Dynamics CRM 2015 give us the ability to add unique identifier fields to entities in CRM. This is particularity useful when you need to store an unique identifier from an external system against a CRM record. At the same time the Upsert command was added to the SDK to facilitate updating records in Dynamics CRM from external applications using alternative keys. You no longer needed to store or lookup the Dynamics CRM Id when the accessing CRM data using the SDK.

Another typical requirement when integrating Dynamics CRM with external systems is to create a hyper link in the external system to open the corresponding record in CRM.  In this post I am going show how you can do this using the alternative key rather than the CRM Id.
This is accomplished by opening a HTML web resource page in CRM passing the alternative key as a parameter and using this to retrieve the CRM Id which is then used to open the form.

In this example I created a HTML web resource page called OpenFormAltKey and added a hyperlink in my external system that opens this page and passes the alterative key of the current record. HTML web resource can only accept a single custom parameter called data so the alternative key need to be encoded in the data parameter,

When the page loads it runs a Javascript function called GetDataParameters to decode the parameters and extract the alternative key. It then calls the function openformWithAlternativeKey which does a Web Api call to get the CRM ID for the account record with the alternative key. It then calls the openEntityForm method to open the account form for the CRM Id. 


    document.onreadystatechange = function () {  
      if (document.readyState == "complete") {  
        var params = getDataParameters();  
        openFormWithAlternativeKey(params["altkey"]);  
      }  
    }  

You take this example and expand it so the entity name and form name could also be passed as parameters making it much more generic and flexible. more code below

Saturday, July 09, 2016

Tracing in Dynamics CRM Custom Assemblies


When writing custom assemblies for Dynamics CRM you can add  trace messages to your code to help track down problems and  identify performance issues. Trace messages can logged by initializing the tracing service in your code and calling the Trace method. I usually add the execution time as part of my trace messages especially when calling external services as this can be a performance pain point which may be difficult to track down.


ITracingService logger = (ITracingService)ServiceProvider.GetService(typeof(ITracingService));

logger.Trace(DateTime.Now.ToString("mm:ss:ffff") + ": Calling FX Rate");
this.callFxRest();
logger.Trace(DateTime.Now.ToString("mm:ss:ffff") + ": FX Rate");




If an exception is raised in a plugin the traces messages are included in the error text returned to the user.


Friday, July 01, 2016

Interactive Service Hub - Sub Account Activity Issue

I have started to have a look at the capabilities of interactive service hub for a potential project. The interactive service hub is a new user interface for Dynamics CRM currently targeted at service functionality. The interactive service hub user interface is very slick and although only a subset of the core entities are supported I strongly believe that this will be come the new default user interface for Dynamics CRM going forward. It uses the tablet layout engine and as a result it is much quicker and responsive. Just like the tablet app you do however get a slight delay when changes have been made as the customizations need to be downloaded to your device.

That said I noticed when checking it out that the surfacing of activities from related records to parent accounts does not seem to work. Using the web client when you look at a parent account the activities, cases and opportunities are rolled up from sub accounts. This gives the user a complete picture of all interactions in a company hierarchy. This does not see to happen in the interactive service hub. If you look at the screen shots below you can see the difference when you view an account in the new ui and the web client.




Tuesday, May 17, 2016

CRM Query Performance using NoLock and Dirty Reads

Using NoLock can provide a performance boast to your CRM code when querying data.  When you use NoLock the sql generated sets the transaction isolation level to  READ UNCOMMITTED. What this means is that your query does not issue any shared locks. Shared locks prevents the data you have read being modified. As a consequence of this it may possible for your query to return "dirty reads".


                QueryExpression qe = new QueryExpression();
                qe.EntityName = "account";
                qe.ColumnSet = new ColumnSet("name");
                qe.NoLock = true;


Dirty reads are where you read data that has been modified but not committed by another transaction. To demonstrate returning "dirty reads"  when using NoLock I did the following.  I created a plugin that triggers on the account create post operation event. The plugin sleeps for a minute if the account name contains the word ghost. This will stop the transaction from committing the database insert until the sleep has completed.

if (entity.LogicalName == "account")
                {
                    if (context.MessageName.ToUpper() == "CREATE")
                    {
                        String name = (String)entity["name"];
                        if (name.Contains("ghost"))
                            System.Threading.Thread.Sleep(60000);
                    }
                }



Monday, April 11, 2016

Dynamics CRM Default Custom Report Template


This is a quick tip which may save you some time if you frequently use Business Intelligence in Visual Studio to develop custom reports for Dynamics CRM. You can create a report RDL file and use this as the default template for new reports. Simply create a new report and configure your CRM data source and add any other common items you require such as headers.




Now take this rdl file and overwrite the report.rdl file in the folder C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies\ProjectItems\ReportProject.
Now when you add a new report it will use this as the template. In the example below new report are created with the CRM data source already configured and with a header section  containing joegill.com.




You can use this technique to create a default report template for any type of reports not just custom Dynamics CRM report.




Monday, April 04, 2016

CRM and SharePoint Security Replication

It is now easier than ever to integrate Dynamics CRM and SharePoint and in this post I will explain a security concern with this scenario and how you can use a tool from Connecting Software to overcome this and to the synchronize security settings between Dynamics CRM and SharePoint

In this example I am using server based integration between Dynamics CRM 2016 and Sharepoint online. I first created a SharePoint site called CRM and gave Everyone access to this site. I then configured this as the default SharePoint site in Dynamics CRM.  Now when you select the Associated Documents option for a CRM record you see a view of the SharePoint folder that is used to store all the documents associated with that record. You can now do all the typical SharePoint tasks like adding documents and checking documents in and out. The SharePoint folder get created the first time you navigate to the Documents option for a CRM record when it will you prompt to create the folder.

Tuesday, March 29, 2016

Email Tracking Office 365 and Dynamics CRM

This post demonstrates how quickly you can configure the CRM app to track emails between Office 365 and Dynamics CRM.  The only precondition is that the users mailbox must configured for server side synch. From the Settings menu select the Apps for Dynamics option.



Click the Dynamics CRM App for Outlook. The installation of the app will run in the background.


Wednesday, March 23, 2016

Web API - Querying with Expand

From version 2016 onwards the Web Api in Dynamics CRM should be the preferred choice for new development as the old rest services are being deprecated. Something I noticed when I started to use the Web Api endpoint is that support for $expand is limited when retrieving multiple records.

The Expand option is used to retrieve related entity data as part of a request uri and for Web Api requests it only works when querying a single record. So for example using the old rest services you could query the accounts entity and use the expand option to also return the email address of the primary contact as follows

//XRMServices/2011/OrganizationData.svc/AccountSet?$select=Name,account_primary_contact/EMailAddress1& $expand=account_primary_contact

If you try and do the same query using the Web Api you will get the error "The navigation properties are not supported with $select clause"

//api/data/v8.0/accounts()?$select=accountnumber,name&$expand=primarycontactid($select=emailaddress1)

Friday, March 11, 2016

Default security role in Dynamics CRM

Many smaller organizations that use Dynamics CRM have simple security requirements. This is typically a single business unit with a small number of security roles. Usually every user has a default security role that can view and update records with a few power users or managers having additional rights on top of this. When you add a new user to CRM you have to assign them a security role before they can login to CRM.

As you may be aware there is a team for every business unit including the root business unit and when you add a new user it automatically becomes a member of this team. So by applying a security role to the root business unit team every user will have this role. In the example below I copied an existing security role and renamed it as the "Default Security Role". I then applied this security role to the root business unit team so it will be applied to every user.

Now when you add a new user you no longer need to give them a security role as they will automatically get the default security role. The only thing you need to careful of is that you set the security roles at business unit level as a minimum. Setting them at user level will not work.

Tuesday, January 19, 2016

CRM Document Templates Some Observations

Document templates were added in the 2016 version of Dynamics CRM to allow users to easily generate Word or Excel documents directly from Dynamics CRM. This  Microsoft link explains how to create and upload a Word template and how to generate documents. However there are a number of things you need to be aware of.

There does not seem to be a way of adding templates to a solution so you need figure out a way to move templates  from one environment to another. You could do this manually or write some code using the DocumentTemplate entity in the 2016 SDK.