LINQPad connections to Dynamics 365 online – Part 1 – The Basics

LINQPad is an invaluable tool for .Net developers in general and for Dynamics developers being able to execute code using the Dynamics365 API using LINQPad can be a real timesaver. Whilst there is a LINQPad driver available for Dynamics here, it has not been updated for a while and I’ve never been able to connect to Dynamics 365 using this driver.
Even if you do manage to get the driver to work, there will be times when you want to create a connection to Dynamics 365 manually – for example if you want to be able to connect to multiple instances in order to be able to compare two environments, or to copy data from one instance to another.

In this multi-part series of articles, I will show you how to configure LINQPad so that creating connections to Dynamics365 can be done quickly and easily. Using the MyExtensions file, you’ll be able to create a shared method for every member of your team to be able to connect to any of your Dynamics environments by just typing a single line of code.

Creating a connection to D365 – the Basics
Let’s start with creating a basic connection to Dynamics 365, using a standard Microsoft Active Directory account.
Create a new LINQPad file of type C# Statement, and add references to System.Net.dll and Microsoft.CrmSdk.XrmTooling.CoreAssembly. (If you have the premium edition of LINQPad, you can download the latter using the integrated NuGet Manager, otherwise you’ll have to download it outside of LINQPad and browse to the file.)

Here’s the code you need to create an organisation service connection:

string username = "YourUsername@YourDomain.onmicrosoft.com";
string password = "YourPassword";

string connectionString = "RequireNewInstance=True;AuthType=Office365;Url=https://YourInstance.crm11.dynamics.com/; Username=" + username + "; Password=" + password;

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
CrmServiceClient connection = new CrmServiceClient(connectionString);

OrganizationServiceProxy orgService = connection.OrganizationServiceProxy;

There are a couple of things to notice here.
Firstly, note the use of TLS 1.2. Microsoft discontinued the use of TLS 1.0 or 1.1 with the Dynamics 365 platform in 2018, so all connections must be made using TLS 1.2.
Secondly, notice the use of the ‘RequireNewInstance‘ option. By default, this is set to False, which in many circumstances is sensible as it allows for the caching of the connection, which makes for faster execution. However, the disadvantage of this is that, if you make a connection to one instance of Dynamics 365, and then immediately to another instance (let’s say you are copying data from one instance to another in a script), you way well find that the second connection is to the same instance which you first connected to, which can be very confusing, if not downright dangerous!

So, now we can make a connection, but there are some further improvements which we might want to make.

Confirmation that we are logged in
Strangely enough, if you use invalid credentials in this code, you will not receive any error. The connection will fail silently, which is not very helpful.

We can, however, trap any errors by inspecting the ‘LastCrmError’ property of the connection:

if (!string.IsNullOrEmpty(connection.LastCrmError))
	{
		connection.LastCrmError.Dump("Last CRM Error");
		connection.LastCrmException.Dump("Last CRM Exception");
		throw new Exception(connection.LastCrmException.Message);
	}

We can quickly validate that we are logged in to the expected instance by displaying the details of the instance URI as follows:

Console.WriteLine("Connected to " + orgService .ServiceConfiguration.ServiceEndpoints.First().Value.Address.Uri);

and we can display the username of the user we are logged in as by performing a WhoAmI request:

Entity user = orgService.Retrieve("systemuser", ((WhoAmIResponse)orgService.Execute(new WhoAmIRequest())).UserId, new ColumnSet("fullname", "domainname"));
Console.WriteLine("Logged in as: " + user["fullname"] + " Domain Name: " + user["domainname"] + "\n");

Can you keep a secret? Using LINQPad’s Password Manager
The next improvement to be made is to start using LINQPad’s password manager so that we don’t keep our passwords in our scripts. Replace the variable holding the password (Line 2 in the first snippet) with this:

string password = Util.GetPassword("MyD365Password");

The first time that you run the script, you will be prompted to enter your password:

Every time you run the script after that, LINQPad will retrieve the password from its secure password store, so you don’t need to enter it every time.
This will also enable the sharing of scripts with other users without having to share login credentials – the passwords are not saved with the script, so each user will be prompted to enter their own credentials. You can save any information in the password manager, so this can also be useful to hold usernames so these are also not saved in scripts. Passwords can be managed (created/updated/deleted) directly in LINQPad, from the File -> Password Manager menu item.

In the next part in this series, I will show you how to manage connections for accounts which use Multi-Factor Authentication.

Posted in Dynamics 365, Dynamics CRM, LINQPad | Tagged , | Leave a comment

Leave a Reply