August 16, 2016

Fix the "Role Error" message when updating security roles

TL;DR: This solution has been posted on Dynamics Community Forums by Nithink.K quoting a Microsoft support answer (link). This post provides an easy solution to fix the issue.

If you have a CRM Online instance and recently you tried to update a security role probably you got the following error:



Role Error - Users cannot add privileges to or change access levels for roles to which they are assigned. For help with changing a role, contact your Microsoft Dynamics CRM administrator.

The error is misleading, because in my case the user had only the "System Administrator" role and I was trying to update the "Sales Manager" role, also the log file didn't provide additional information, it just contained the message "Invalid privilege depth".

A solution has been posted on Dynamics Community Forums (you can find the whole thread here) and it's about a wrong privilege that has been assigned to the "Data Performance Dashboard" entity under the core records. This OOB entity is "Organization" type (meaning the privilege can be only "Organization" or "None") but in the CRM Online instances affected with this problem, the privilege is set to "User":



The solution is to set the privileges to "None", after this change the security role can be edited or copied again. I started a new CRM online trial and the correct configuration is "None" for all the security roles except System Administrator (that can't be customized) and System Customizer that has these privileges set to "Organization".

Because it's a tedious process to edit all the security roles one by one, you can use the "Role Updater" tool included inside the XrmToolBox, with this tool you can bulk update the security roles removing or adding privileges in few clicks.

After you started the tool, click on "Load Roles and Privileges" button and select all the users except "System Administrator" and "System Customizer"



After you click "Next", search for "data" and select the privileges related to "Data Performance Dashboard" entity and click the "None" button



When you are ready click the "Next" button and the privileges will be updated. Regarding the System Customizer role, you can edit it manually or use again this tool, select only the role and click on "Organization" instead of "None".

After this procedure you will be able to edit again your security roles, hope it helps!

February 12, 2016

CRM 2016 Web API and plural names

The new Web API available for CRM 2016 is based on OData V4 protocol and the endpoint is /api/data/v8.0/

The MSDN contains several examples of the new endpoint, for example if we want to retrieve the top 3 accounts:

/api/data/v8.0/accounts?$select=name&$top=3

Simple, right? if you want to retrieve from account entity you write accounts, if you want to retrieve from contact entity you write contacts, if you want to retrieve from opportunity entity you write opportunities. You write the plural.

What a poor choice to use the plural form instead of the singular one, and let me say something, the root of the problem is an English-centered vision.

I'm not an expert of REST and OData protocols, maybe they suggest to use the plural forms but when you let users dynamically add entries to the endpoint (i.e. creating an entity) the use of plural forms is a mess.

A user on Dynamics Community asked a question: "my custom entity name is xxx_settings and I can't query using the endpoint /api/data/v8.0/xxx_settingss, which is the right syntax?"

Well, in this case the answer is simple, who designed the API decided to apply the exceptions, so if the noun ends with s the plural is es, in the user's case the correct endpoint is /api/data/v8.0/xxx_settingses, but if you want to be sure about the name you can check the metadata at this url: /api/data/v8.0/ or download the XML from the Developer Resources inside CRM UI.

Now let's play a game, how much are robust the exceptions they implemented in order to create the plural form? The answer is weak.
English is not my first language so I googled "plural exceptions english" and I landed in this page: A handout on irregular plural noun forms. I started to create some custom entities, here some results:
new_city become new_cities, English correct.
new_wolf become new_wolfs, English incorrect.
new_knife become new_knifes, English incorrect.
new_man become new_mans, English incorrect.

Now, I don't expect that all the irregular forms are covered, but if you decide to handle the final 's' and the final 'y' why not handle the final 'f'? However not big deal, You check the metadata and you can find the exact plural word to use.

BUT, and there is a BUT

Let's say we created our custom entity new_city and now the REST endpoint responds to /api/data/v8.0/new_cities, what will happen if we create a custom entity called new_citie?
The entity is not listed inside the REST endpoint!!! because the plural of new_citie is new_cities but it's already used by new_city.
The lesson is: pay attention when you name your entities if you need to query them using the new REST endpoint, if the plural form of a new entity is the same of the plural form of a previous entity, you can't query it.

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)

January 2, 2016

Another year with the MVP community

Yesterday I received my second MVP Award and it's a great way to start the New Year!
Be in the first quarter (or in the second one due to April Fools' Day) is a bit thrilling but worth the wait. Last October the MVP program made some changes, so my award category is now called Business Solutions and includes MVPs from the Dynamics family (CRM, AX, GP, NAV) and from Microsoft Project.

An anniversary is also a moment to look back and see what was done last year. Personally I contribute to these sites: Dynamics Community, MSDN Forums and StackOverflow.

I start with the last. StackOverflow doesn't have a so good reputation inside the Dynamics CRM community, probably because it's not the right place to ask all the questions, it's a site for developers, it has rules and you can't just drop there and ask: "How do I install the Email router?", but it's a great community with extraordinary members.

MSDN has forums for CRM questions, but I noticed in the last year that the number of questions asked there is lower, there are also some regional CRM forums (like in German or French) but I don't know if this trend I noticed affected also that part.

Dynamics Community had a huge increment of participation: more questions, more active users, more feedback. It's a site for everybody, beginners and experts, a great community, probably THE Dynamics CRM community, you can find everybody there.

Last year I also coded a bit and released two small utilities: a library to handle Moment.js multi language inside Dynamics CRM and a Theme Generator.

The library for Moment.js is a small thing, you can find details here but it got a mention on CRM Tip Of The Day.

The Dynamics CRM Theme Generator had more success, it has daily visitors and was mentioned or reviewed in some CRM articles, in particular this one that I like very much:

My Eyes! How to Create Jarring Themes Using the Theme Generator

2015 was a long and full year and I hope 2016 will be Harder, Better, Faster, Stronger!

Guido
ps: I started a new blog (8086.it)

December 2, 2015

India and Canada Data Center Discovery URLs

In the last months Microsoft announced the opening of new data centers for Dynamics CRM Online in India and Canada.
These data centers are not available yet, but Microsoft defined the Discovery Web Service URLs. The addresses are:
https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc (India)
https://disco.crm3.dynamics.com/XRMServices/2011/Discovery.svc (Canada)

The Indian data center is identified by the crm8 host, the Canadian one by crm3. This will affect also the organization url, for example if Contoso Ltd. has two branches, one in India and the other one in Canada, their urls will be:
https://contosoindia.crm8.dynamics.com
https://contosocanada.crm3.dynamics.com

The relative MSDN page has NOT been updated to include this change, the next table is a recap:

HostLocation
crmNorth America
crm4EMEA
crm5APAC
crm2South America
crm9North America 2 (CRM Online for Government)
crm7Japan
crm6Australia
crm8India
crm3Canada

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