Showing posts with label plugins. Show all posts
Showing posts with label plugins. Show all posts

January 7, 2016

Pay attention to the CRM version when using the SDK NuGet packages

Microsoft publishes the CRM SDK DLLs also as NuGet packages, you can find the list by browsing the crmsdk profile:

https://www.nuget.org/profiles/crmsdk

Because the packages are not separate by CRM version (for example a package for CRM 2015 and a package for CRM 2016) Microsoft simply updates the NuGet package increasing the version.
This can be an issue in some projects as happened to me some days ago. I was working on a plugin for CRM 2015, my project was targeting .NET 4.5.2 and I installed the current version of CoreAssemblies (8.0.1).
The build was successful but the plugin always returned the exception "Value cannot be null".

I spent some time to understand that the problem was the referenced DLL version, so I removed the NuGet package and I installed the 2015 specific version (7.1.1) using the Package Manager Console:

Install-Package Microsoft.CrmSdk.CoreAssemblies -Version 7.1.1

After the plugin worked like a charm.
As reference these are the current versions and the suggested .NET framework to use:
  • CRM 2011: 5.0.18 (.NET 4.0)
  • CRM 2013: 6.1.1 (.NET 4.0)
  • CRM 2015: 7.1.1 (.NET 4.5.2)
  • CRM 2016: 8.0.1 (.NET 4.5.2)

July 21, 2015

Visual Studio 2015 Shared Projects and CRM Plugins Development

Visual Studio 2015 is now available and inside the new features and improvements there is one that I like very much: Shared Projects. A Shared Project is intended to share easily the code between different platforms.
For C# projects this was already possible using (portable) class libraries and adding the assembly to the main project references.

Which is the big advantage of Shared Projects for a Dynamics CRM developer?
With Shared Projects the code is NOT compiled to a separate assembly but directly inside the main assembly of your project.

This is can be very useful for Plugin and Custom Workflow Activity development, because now we can create a common library with CRM methods to be used inside our plugins WITHOUT the need to use ILMerge for creating a single assembly in order to be registered inside Dynamics CRM.

As example I created a small shared project containing a simple method to check the current CRM Version:
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
namespace CRM.Common
{
    public static class Utils
    {
        public enum CRMVersion
        {
            Unknown = 0, CRM2011 = 2011, CRM2013 = 2013, CRM2015 = 2015
        }

        public static CRMVersion GetCRMVersion(IOrganizationService service)
        {
            RetrieveVersionRequest versionRequest = new RetrieveVersionRequest();
            RetrieveVersionResponse versionResponse = (RetrieveVersionResponse)service.Execute(versionRequest);
            string version = versionResponse.Version;
            if (version.StartsWith("5")) { return CRMVersion.CRM2011; }
            if (version.StartsWith("6")) { return CRMVersion.CRM2013; }
            if (version.StartsWith("7")) { return CRMVersion.CRM2015; }
            return CRMVersion.Unknown;
        }
    }
}
After I created a normal Class Library project for my plugin and I added the Shared Project to the solution and a reference inside the Class Library:

The plugin code is very simple, it throws an exception indicating the CRM version:
using Microsoft.Xrm.Sdk;
using System;
using static CRM.Common.Utils;

namespace CRM.MyPlugin
{
    public class MyPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            CRMVersion version = GetCRMVersion(service);
            throw new InvalidPluginExecutionException(version.ToString());
        }
    }
}
If we compile the solution only a single assembly is generated and if we analyze it using ILSpy we can confirm that the Shared Project is compiled inside the main assembly:

And the plugin works without issues:


Shared Projects can be very useful for Dynamics CRM development because will definitely improve the quality and the reuse of the code.

Shared Projects are also available for Visual Studio 2013 as separate addon, you can download from here: Shared Project Reference Manager

February 9, 2015

JSON and CRM Sandbox Plugins

Today I was working on a plugin and one of the requirements was a call to a web service passing some POST parameters, nothing complicated but I want to share part of the process.

Normally I register my plugins always inside Sandbox, the main reason is that I don't need to care where the plugin is executed (in this specific case the development is OnPremise but the production is Online), the second reason is that my user is often forgotten to be added as Deployment Administrator :)

One of the parameter was a JSON Object passed as string, practically I needed to do the C# equivalent of a JSON.stringify in order to pass a complex structure. An example can be the following Course object (JavaScript):
var Course = new Object();
Course.Name = "CRM Development 1";
Course.Teacher = "Prof. John Smith";

Course.Students = new Array();
Course.Students[0] = new Object();
Course.Students[0].ID = "001";
Course.Students[0].Name = "Walter Davis";

Course.Students[1] = new Object();
Course.Students[1].ID = "002";
Course.Students[1].Name = "Mark Harris";

var parameter1 = JSON.stringify(Course);
Because I was inside a Sandbox plugin I couldn't use the Newtonsoft.Json library and I didn't want to waste time trying to merge it inside my plugin.

The .NET framework provides different methods to create a JSON output, in particular JavaScriptSerializer (from System.Web.Script.Serialization namespace) and DataContractJsonSerializer (from System.Runtime.Serialization.Json namespace).

JavaScriptSerializer is very easy to use (it has a Serialize method returning a string) but doesn't work inside Sandbox, so I used DataContractJsonSerializer:
Course course = new Course();
// ...

string parameter1 = "";
using (MemoryStream memoryStream = new MemoryStream())
{
   DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Course));
   serializer.WriteObject(memoryStream, course);
   parameter1 = Encoding.Default.GetString(memoryStream.ToArray());
}
A bit longer code but compatible with Sandbox and CRM Online.

May 22, 2014

The revamped Plugin Registration Tool

One of the suggestions I always give when a user has issues with the Plugin Registration Tool is to download first the latest CRM SDK.
The reason is simple: a new rollup installed or a CRM Online update can easily bring some changes with the previous versions of the tool, but if we use the latest version we can hope that the Plugin Registration Tool will work as expected.

Of course I never follow my suggestions, so it took me 2 weeks from the release of the latest CRM SDK (6.1) to discover the new Plugin Registration Tool!


It's easy to spot the switch from the ugly Windows Forms to WPF (Windows Presentation Foundation).

More important is the new position inside the SDK. Now the Plugin Registration Tool is located inside the folder SDK\Tools\PluginRegistration and not anymore inside the folder SDK\Bin.

Another change is the .NET framework required to run the tool, now you must have 4.5 installed:


But the main change is how the connection is handled, in the previous versions was necessary to insert the mysterious discovery url:


The new version is more user-friendly:


First it is necessary to specify the Deployment Type, between On-Premises, Online and Office 365.
For On-Premises is possible to specify the Authentication Source between Active Directory and Internet-facing deployment(IFD) and to use or not the default credentials.
For Online and Office 365, the user can select the Online Region (there is also the option Don't Know)


The functionality of the Plugin Registration Tool is still the same (register and update the plugins, install the profiler, ...) only the Properties box is positioned at the bottom (it is useful to check the assembly version)


A big welcome to the new Plugin Registration Tool!