Hosk’s Top CRM Articles of the week – 3rd July

Article of the week

 

Top Ten Secrets to a Successful CRM Deployment: Part Two–Process

great blog post from CRM MVP Leon tribe.  This list has some great advice on helping to ensure you CRM project is a success.

Here is a post focusing on the other way your project can go

13 signs your CRM project is doomed

Best of the rest

CRM Plugins – Stopping infinite loops and understanding PluginExecutionContext.Depth

Whilst using Depth to stop a plugin being called from another plugin, I decided to have a read of the CRM SDK to find out more about PluginExecutionContext.Depth

Create or Update through a single request – Upsert in Dynamics CRM 2015 Update 1

The might new and amusingly named Upsert.  Very useful but you need to learn about alternative keys and think about the side effects of other plugins being triggered.  Good article on the subject to get you started

CRM 2015 – plugin deployment options

Do you know your Plugin deployment options?  How about the effects of IISReset?  This article talks about the Plugin framework as well.  It was written by The Hosk, who is a good friend of mine

Top Ten Secrets to a Successful CRM Deployment: Part Three–Technology

A list of the juicy new features in CRM 2015

Dynamic Form Navigation

Showing you how to change the form dynamically using Javascript

Convert CRM Plugin Message to CRM Alert or Notification When Save Programmatically JavaScript

Interesting, well written and useful article on pushing plugin errors messages into notifications.

new page for Microsoft Dynamics CRM books and videos

Microsoft has got a swanky new page so you can easily find CRM books and videos, which is good for customers.

Improve validation and user experience by using business rules to set default values 

Simple idea but using business rules to set default values easily solves an annoying issue with CRM

Assembly versioning in CRM 2011

An old but classic article discussing versioning in CRM plugins/Custom workflows. I bumped into this whilst writing by blog posts this week.

Tips: CRM C# Create Validated Parent and Child Records at Once as one Big Compound using ‘Related Entities’ 

How to avoid infinite loop errors when a parent case updates children casess

CRM 2013 – Step by Step Update Plugin Tutorial using the CRM 2013 Development Toolkit

A step by step guide to writing a plugin using the CRM developer toolkit

Simple web API preview sample

The Web API is my first glimpse of OData 4

The difference: Xrm.Page.data.refresh() vs Xrm.Utility.openEntityForm(entityName, id) in Practice

What’s the difference between refreshing and reloading? Read the article to find out

programming

Great article and examples of Dependency Inversion Principle – DIP in the Wild

Uncle Bob DIP

Misconceptions about code reuse

I’m Sorry, But Agile Won’t Fix Your Products

High Cohesion and Low Coupling part 1

High Cohesion and Low Coupling part 2

December 2014: From Test Driven Development to Behavioral Driven Design

The 10 Worst Kinds of Software Developers! which one are you?

Other

Office workers – Get up and get active 

One man’s year as a nudist

10 Most Common Rookie Mistakes in Public Speaking

Meditation Changes Your Brain for the Better, Even if You’re Not a Monk

Has Consciousness Evolved?

Putting the Greek back into Stoicism

The Three Marriages: Our Relationship With Ourself

PERHAPS THE MOST IMPORTANT BUSINESS BOOK WRITTEN IN THE LAST FIFTY YEARS

Previous top picks

Hosk’s Top CRM Articles of the week – 26th June

Useful Hosk Links

Hosk list Of CRM 2013 Tools

A list and review of CRM 2013 tools, this will probably work in CRM 2015 as well

Hosk’s CRM Developer Articles

A collection of my favourite CRM Developer articles I have written

MB2-703 – CRM 2013 Customization and Configuration Certification Information

All the CRM 2013 content to help you pass the exam

HoskWisdom – Hosk Developer Quotes

 Words of Wisdom from the Hosk.  I have written over 900 articles, surely I should have said a few memorable things

CRM Plugins – Stopping infinite loops and understanding PluginExecutionContext.Depth

In the previous post I looked at Plugin Deployment Options, which looked at the various different deployment options Database, Disk or GAC.  The article looked at the async architecture and effects of ISSResets and CRM service restarts.

This post I am going to look at a couple of the parameters in the PluginExecutionContext which I needed to help me resolve a problem.

What is PluginExecutionContext

Unit testing plugins is difficult due to a plugins dependency on

IServiceProvider serviceProvider

The serviceProvider has these variables inside

  • IPluginExecutionContext
  • ITracingService
  • IOrganizationServiceFactory
  • you use the IOrganizationServiceFactory to create IOrganizationService

Mocking the IServiceProvider and IPluginExecutionContext can be tricky because they contain a lot of variables you would need to setup.

I prefer to put the code logic into separate classes which take IOrganisationService, ITracingService, Entity being changed and other variables I need.  I focus on testing the plugin logic and not get bogged down creating variables

The IPluginExecutionContext holds contextual information passed into a plugin. This information is different for each type of plugin because it contains things like

  • Stage
  • primaryentityid
  • parentContext
  • InputParameters (e.g. which holds the Target)
  • etc

To get the plugin runtime variables you need to get the PluginExecutionContect in your plugin, I’m going to assume you are using the CRM Developer toolkit

LocalPluginContext localContext
IPluginExecutionContext context = localContext.PluginExecutionContext;

You now have access to the plugin runtime variables, here are a few

context.Depth
localContext.PluginExecutionContext.Depth;

IOrganizationService service = localContext.OrganizationService;

ITracingService tracingService = localContext.TracingService;

context.InputParameters.Contains("Target")

context.ParentContext

This is how CRM SDK describes it (remember always start with the CRM SDK)

Defines the contextual information passed to a plug-in at run-time. Contains information that describes the run-time environment that the plug-in is executing in, information related to the execution pipeline, and entity business information.

A list of all the available parameters is listed on PluginExecutionContext  properties page.

PluginExecutionContext is a fancy way of saying the plugin variables at run time.

Depth and ParentContext are two of the many properties passed into plugins in the PluginExecutionContext.  I shall start with depth first

What does Depth do?

CRM SDK Definition of depth at the ready

Int32 – The the current depth of execution in the call stack.

Hosk Definition

Depth is the number of times a plugin/custom workflow has been called in one transaction

What is depth used for?

Depth is often used to stop infinite loops where a plugin updates a value which triggers the plugin to run again

A common cause of this is bad programming practise where a plugin retrieves the target entity and at the end of the plugin updates the entity.

e.g.

A post plugin triggered on update of account name.

Plugin retrieves target entity

plugin updates name field on target entity field to name + unique number

plugin does CrmService.Update (target entity);

Plugin has updated field value which triggers plugin again
The way around this is to put code in a pre plugin. It’s possible to check the depth of the plugin

e.g.

IPluginExecutionContext context = localContext.PluginExecutionContext;
if (context.Depth > 1)
     return;

The code above is checking to see if the context.Depth is greater than one. If a plugin is triggered from a record being saved then the context.Depth = 1 (it has been run once). If the plugin called itself again the depth would then be incremented to 2.

I would put the context checking code as bad programming practise, it’s fixing the problem of stopping the infinite plugin but it’s working around the plugin being triggered in the wrong time (e.g. post instead of pre).

There are some cases when a plugin might need to update itself but for the majority of the time avoid doing because it’s confusing/complex and there is usually a better way.

Good practice when updating entity

When you want to update fields on a record, it’s good practice to create a new entity or early bound type of the record and only add the fields you want to update.

By only updating the fields you are changing you reduce triggering other plugins running needlessly.

Do not update the retrieve Target entity because it will update all fields included in the target entity.

How does depth work?

When a plugin/custom workflow triggers another plugin/trigger then the depth property is incremented by one.

The depth value has a maximum value called WorkflowSettings.MaxDepth.  The CRM SDK (Depth)states this is set to maximum depth of 8 within one hour.

You can adjust this setting by changing WorkflowSettings.MaxDepth via powershell. My advice is to not change this setting because it usually means you are trying to work round bad practice rather than resolve the bad practice.

e.g. fix the problem not react to the problem

If a plugin/workflow hits the depth of 8 or greater then it will not run and I think throw an error.

The maximum depth is not such a problem for plugins because if it reaches 8 it’s usually because there is a loop and it happens quickly.

Workflows are different, it’s easily possible for a workflow to get triggered plenty of times by one record. I have seen workflows which have been created to keep polling/checking a value hit the depth max.

What is ParentContext?

PluginExecutionContext.ParentContext will return a IPluginExecutionContext context object of the triggering plugin/custom workflow if there is one, otherwise ParentContext will be null (if it was called from the Form)
Plugins don’t just trigger themselves in a loop, often the CRM developer will trigger another plugin by doing a CRMService.update() or an assign using the CrmService(IOrganisationService)

When you trigger a plugin in the same transaction then you will increment the context.Depth by 1.

Not only does the depth get incremented, so the depth = 2 in the triggered plugin. The context.ParentContext will now contain a value.

The CRM SDK describes ParentContext

The execution context from the parent pipeline operation.

and

This property may be populated for a plug-in registered in stage 20 or 40 when a Create, Update, Delete, or RetrieveExchangeRate request is processed by the execution pipeline.

This can be useful if you want to know if your plugin was triggered by a CRM form update or triggered from another plugin.

If a plugin is triggered from another plugin then the context.ParentContext will not be null and the localContext.PluginExecutionContext.Depth will have a count of 2 (or higher if it has been called more than once).

The ParentContext can be useful because it can give you more information about the calling plugin which you might want to use/use for filtering.

Depth checking and stopping infinite loops in plugins

The common method to avoid a recurring plugin is to check if  a plugins depth > 1.  This would stop the plugin from being run if was triggered from any other plugin.  The plugin would only run if triggered from the CRM form.

This can resolve the problem of plugins firing more than once but it stops plugins being triggered from other plugins, this might not be the functionality you require.

This article below shows you how test for infinite loops using depth but it’s basically this

if (context.Depth > 1)
	return;

or you could do this

if (context.Depth > 1 || context.ParentContext != null)
	return;

CRM 2011 Plugins – Avoiding Infinite Loops

An alternative solution is to use SharedVariables, talked about on this page Pass data between plug-ins.  You can use ShareVariables to pass information between plugins registered on different stages but in the same transaction e.g a pre plugin can pass information to a post plugin.

It’s possible to set a shared Variable to a value and then check to see if the share variable exists, if it doesn’t have a value you know the plugin has not been run before, if it does have a value the plugin has ran in the transaction.

This blog gives you an example of a shared variables

These two forum discussion shows an interesting example of trying a parent record updating child records of the same type.

How to prevent infinite looping without ExecutionContext.CallerOrigin in Microsoft Dynamics CRM 2011?

CRM 2015 – plugin deployment options

I was asked this question today

Do I need to restart IIS (Internet Information Services) after I have deployed my plugin?

My initial quick answer was no but then I was curious why they asked me the question? This is what I refer to as a suspicious question.  Often the question people ask, isn’t the real question they want to ask, a bit like when my 3 year old daughter asks.

“What’s that chocolate bar doing on the table Daddy?”

The real question

“Daddy I want to open and eat that delicious looking chocolate bar”

This picture isn’t my child but it’s a fits the text above

Plugin storage options

There are three plugin storage options

  • Database
  • Disk
  • GAC

deployment options

The options are fairly self explanatory.  (plugin.dll is your custom plugin assm)

  • Database = Plugin.dll uploaded into the database
  • Disk = The Plugin.dll is saved on the CRM Servers hard disk
  • GAC = The plugin.dll is loaded into the GAC on the CRM Server.

If you don’t know what the GAC is it’s the Global Assembly Cache.  It’s a common area on a computer to store the DLL’s which is C:\Windows\assembly.   This discussion has a good definition – What is the GAC in .NET

As always Start with the SDK, which has a good article on the subject

Register and Deploy Plug-Ins

Default Option

The default option should be store your plugin on the database and to be honest I can’t think of any reason why you would store you plugin not in the database.  Microsoft STRONGLY agrees with me (excellent, I like it when Microsoft does that)

We strongly recommend that you store your production-ready plug-ins in the Microsoft Dynamics CRM database, instead of on-disk.

The advantages of deploying your plugin to the database our

  1. The plugin is backed up when the database is backed up
  2. For multiple server configurations you only need to deploy once to the database and not individually to each CRM server.
  3. Plugins in the database can be added to solutions, Disk, GAC plugins cannot
  4. Plugins deployed to the GAC or Disk will need an IISRESET to refresh, plugins deployed in the database do not.
  5. Sandboxed and CRM Online plugins have to be deployed in the database

If you want to understand what deploying to the Sandbox is read my blog post Understanding Plugin sandbox mode

I have experienced a CRM deployment where common code used by the plugins was held in a separate DLL which was stored in the GAC of the CRM servers.  The preproduction environment had 8 CRM Servers and the Production environment had 11 CRM servers.  It was a tedious job to install the DLL on every server, restart the ISS server and CRM async services.

I cannot think of any advantages to installing CRM plugins on the server or in the GAC so my advice is never to do it.

Some people might think you need to install the plugin.dll on the CRM server to enable remote debugging but this isn’t true, you can install the plugin.dll in the database and put the pbd file in the the folder C:\Program Files\Microsoft Dynamics CRM\Server\bin\assembly.  Microsoft gives you this tip on the Debug a plugin page

It is possible to debug a database deployed plug-in. The compiled plug-in assembly’s symbol file (.pdb) must be copied to the server’s <crm-root>\Server\bin\assembly folder and Internet Information Services (IIS) must then be restarted. After debugging has been completed, you must remove the symbol file and reset IIS to prevent the process that was executing the plug-in from consuming additional memory.

Personally I prefer to use the plugin registration tool to debug plugins because this can be done a CRM Developers individual machine.  When people remote debug on the CRM server this can sometimes slow, stop the CRM Async services from running and processing other plugins.

Basically it’s not good CRM developer etiquette to stop other developers using the system because you need to debug a plugin (although sometimes need must).

A better system is to write unit tests to test the logic of your code in isolation

CRM MVP Gonzalo Ruiz has written a great article on the benefits of registering your plugin to the CRM database.

6 Great Reasons to Register your Plugins in Database Instead of Disk/GAC

Point number 4 is interesting

4. Disk assemblies will not support multiple versions

I never realised (or yet needed/wanted to use) you can store multiple versions of an assembly.

I found one small reason for deploying to disk, highlight by this blog by David Jennaway, where he mentions if you plugins have dependant dll’s you can put them in the same directory as the plugin, in a similar way the plugin registration tool has the CRM SDK dll’s in the same directory but this isn’t much of a reason.

What can you restart and how does it effect plugins

There are a few things which you can restart which can affect your CRM plugins.  I will state plugins deployed to the CRM database do not need any of these restarted, which is another good reason to deploy your plugins to the CRM database.

  • IIS Server
  • Recycle CRM App pool
  • Restart CRM Services

You do sometimes need to check the IIS Server or CRM services if your CRM isn’t working, for more detail check out the article Microsoft Dynamics CRM not working? check these common causes

IIS Server

Lots of CRM developers I have met do an IIS Reset and Async CRM Services restart when ever they deploy a plugin, even when the plugin is deployed in the database and they didn’t need to.  The reason they did this was because the CRM developer who helped them learn CRM did it, so now they do it.

First lets understand what doing an IIS Reset does.  When you type IISRESET into the cmd line or go to the IIS server and click restart.  The first thing you should do is warn the users you are about to take down CRM and all other websites and web services hosted in IIS.  The key point is it restarts everything on the IIS server and not just CRM, make sure you want to restart everything.

IISRESET restarts these services, it’s the same as stopping and then starting the three services below according to this post 

  • IIS Admin Service
  • Windows Process Activation
  • World Wide Web Publishing

This discussion has an excellent summary what IISReset does What does an IISReset do?

IISReset stops and restarts the entire web server (including non-ASP.NET apps)
Recycling an app pool will only affect applications running in that app pool.
Editing the web.config in a web application only affects that web application (recycles just that app).
Editing the machine.config on the machine will recycle all app pools running.

IIS will monitor the /bin directory of your application. Whenever a change is detected in those dlls, it will recycle the app and re-load those new dlls. It also monitors the web.config & machine.config in the same way and performs the same action for the applicable apps.

useful tip – If you are doing an IISReset via command line then it’s a good to do

IISReset /noforce

This will gracefully close down IIS rather than IISReset and wait for processes to finish.  IISReset will abruptly close down IIS which could leave processes half way through updating the CRM database! which is something you want to avoid.

This discussion highlights an area where you need to recycle the app pool

Do we really need IIS Reset and Async Services restart when we depoly plug-in or custom workflow – CRM 2011

There is one other scenario where you need to recycle the CrmAppPool application pool. If you modify the parameters that are available for a Custom Workflow Activity, then CRM will not make any new parameters available when editing the workflow until after recycling the application pool.

Recycling the CRM app pool is a lot less disruptive than restarting the whole server.

I couldn’t find any need to do an IIS reset for database stored plugins, I think you would need to recycle the app pools to if you your plugins are stored in the GAC or Disk.

CRM Services

You have a number of choices when deploying plugins which effects what CRM process runs the plugin code.  Here are the CRM services

CRM services

Isolation mode

  • Sandboxed
  • none

If you choose Sandboxed the plugin code will be run in CRM Sandboxed Processing services, this service is sandboxed, if the plugin tries to modify or access external dll’s, certain system resources an error will be thrown.

if you choose none it gets run by the core CRM system in the event execution pipeline if it Synchronous, if it’s asynchronous it gets run by the CRM async service

CRM Async services

I have written before about CRM 2013 – Understanding SystemJobs and Async Plugins.

If you look at the msdn article – Event execution pipeline, this picture shows you the various parts of CRM

Synchronus plugins runs straight away and the CRM form will hang until the plugin has successfully run.  Looking at the architecture above you can see synchronus plugins get run in by the core CRM system inside the database transaction.

Async Plugins get run after the  Plugin execution pipeline has finished and go into the Async Queue Manager and get run when CRM has free resources.  Researching this topic today I found Microsoft has quite a large section on Asynchronous services in CRM, which I have never read until today

Asynchronous service in Microsoft Dynamics CRM

This article Asynchronous service architecture is mentions this

The asynchronous service features a managed queue for the execution of asynchronous registered plug-ins, workflows, and operations such as bulk mail, bulk import, and campaign activity propagation. These operations are registered with the asynchronous service and executed periodically when the service processes its queue. The asynchronous service can be hosted on a server other that the server running Microsoft Dynamics CRM.

The reason I mention the Async service is because there is a small piece of best practise I had not considered or heard before tucked in the

You should stop the asynchronous service before you unregister a plug-in that was registered to execute asynchronously. Stopping the service prevents a situation where an asynchronous registered plug-in has been queued for execution but for which there is no plug-in assembly currently registered. For example, consider the situation in which a plug-in has been registered to execute asynchronously and the related event has fired. After the asynchronous operation has been queued by the queue manager, you then unregister (delete) the plug-in assembly from the Microsoft Dynamics CRM database. In this case, an error occurs when the asynchronous service tries to execute the queued asynchronous operation but the plug-in assembly no longer exists.

So if you have Async plugins then it’s good practise to restart the CRM Async service when you unregistered an async plugin.  This will avoid a plugin being queued which has been unregistered.

Finally I will leave you with the my post on common plugin errors and isolation mode

CRM 2011/2013 – Common Plugin Errors and Isolation Mode

Back to the question

I forgot about the question. The answer is no the developer won’t have to do an IISReset if the plugins are deployed to the database, which they were.

It’s been interesting researching this topic and I have learnt a bit more about the CRM architecture

Hosk’s Top CRM Articles of the week – 26th June

Article of the week

CRMDeveloperExtensions from Jason Lattimer

I just want to let people know, Jason Lattimer has uploaded his CRM Developer extensions to Github, so download it and have a play.

Top Ten Secrets to a Successful CRM Deployment: Part One–People

Great article from Leon Tribe on the secrets to a successful CRM deployment.  There are lots of pieces, lots of people, lots of customizations, lots of data.  You need to herd them all in the direction of success

Best of the rest

CRM 2015 – CRM developers should think in Entities

Hosk blog post on why CRM developers should view everything as entities.

Pass Plugin Context Message C# Exception to Form Script (Javascript) during CRM Ribbon Calling Action

How to catch plugin errors in your javascript

Compare This Year to Last Year with a Dynamics CRM chart

The CRM Chart master gives another chart master class

#IoT2CRM: The gateway revised

I enjoyed reading this article, an interesting piece of using Gateways and thinking about the data you use in CRM projects

CRM 2013 – How to stop these annoying things in Microsoft Dynamics CRM

There are a few annoying things which feels good to squash and stop.  Liking pending emails, annoying welcome woman, incorrect format, send report pop up etc.

Rolling in a New Feature to Stay Updated in Dynamics CRM

I like the quirky way you can use rollup fields and it’s daily rolling up functionality.  It would be good if CRM had schedule functionality

Hide / Show Export to Excel button for specific Entity / Specific View

How to hide the export to excel button for individual entities

CRM 2015 – how to find Statecode value

A quick way to find a statecode value

How to Add Parameters to a Fetch Based Report

A good blog showing you how to add parameters to fetch based reports.

The Workflow Executor for CRM2011, CRM2013 and CRM2015

CRM systems can have lots of workflows in various stages.  This free tools lets you set the status for many workflows at once.

Tip #418: 3 ways to find the blocking attribute

3 ways to find an attribute

Did you know

Explanation of some of the default fields

programming

Joel Spolsky : The law of leaky abstractions

Three great articles on debugging

https://medium.com/@codingpains/the-most-powerful-debugging-tools-in-the-world-part-1-9e4e20a622dc

https://medium.com/@codingpains/the-most-powerful-debugging-tools-in-the-world-part-2-967dc01e9960

https://medium.com/@codingpains/the-most-powerful-debugging-tools-in-the-world-part-3-d596176ded82

The Startling Cost of Losing a Developer

Think twice before logging

34 CSS Puns That’ll Make You Laugh, Even If You Aren’t A Web Designer

Continuous Delivery Among the Donkeys

How peer review leads to quality code

other

Shhh, Google Chrome is listening

8 Things Every Person Should Do Before 8 A.M.

Windows 10 inside story

Probability Trumps Predictions When Making Forecasts

How It’s Made Series: Beats By Dre

Exclusive: Satya Nadella reveals Microsoft’s new mission statement, sees ‘tough choices’ ahead

Hearthstone: how a game developer turned 30m people into card geeks

Previous top picks

Hosk’s Top CRM Articles of the week – 19th June

Useful Hosk Links

Hosk list Of CRM 2013 Tools

A list and review of CRM 2013 tools, this will probably work in CRM 2015 as well

Hosk’s CRM Developer Articles

A collection of my favourite CRM Developer articles I have written

MB2-703 – CRM 2013 Customization and Configuration Certification Information

All the CRM 2013 content to help you pass the exam

HoskWisdom – Hosk Developer Quotes

 Words of Wisdom from the Hosk.  I have written over 900 articles, surely I should have said a few memorable things

CRM 2013 – How to stop these annoying things in Microsoft Dynamics CRM

There are a few common and very annoying problems that annoy me with CRM, so I have decided to group them together in this blog so I can easily and quickly find how to stop them.

Disable Send Report to Microsoft pop up

I personally have always wondered what Microsoft does with all those error reports it asks people to send!

You might be tired of clicking on these message and you probably don’t want your end users to see this popup.

Good news – Luckily Microsoft have added a setting we can turn off

Bad news – it’s hidden in a place where no one would dream of looking

If you want to stop this message, you need to go to

Settings –> Administration –> Privacy Preferences –> tick box and select Never send

privacy settings

Users get created with the wrong format

This is a common and annoying problem for UK CRM Developers.  You create a new organisation which as the default English (United States).  This is clearly no good for UK users because the Americans have got their months and days mixed, currency dollars etc.

All the users you add will be given the same Format settings as the default.

Once a user is created the only way to change their format settings is to go into their personal options and change the format settings.

The way to avoid setting users with English (United States) is to change the Current Format in the System Settings to English (United Kingdom) and then create your users.

Stop the Annoying Welcome Woman

To do this you have to add a registry key.  I found the instructions on the awesome power object blog How to Disable the CRM 2013 Welcome Screen

On the CRM server in open Regedit

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM

Add a new DWORD (32-bit) and call it DisableNavTour

Disable Hello woman

Annoying outlook download message

Microsoft is always trying to persuade people to download Outlook, if you have got annoyed at this message you can turn it off by flicking a switch in System Settings

Outlook message turn off

Get rid of annoying pending email warning message

The annoying pending email message has plagued me a number of times.  There are two ways to get rid of it.

1. Delete the pending emails, instructions here

2. Modify CRM Server registry setting DisablePendingEmailReminder to 1.  Instructions in this blog

CRM 2013 Navigation is slow and tricky

Quite how Microsoft made CRM 2013 slower and more difficult to navigate than CRM 2011 is a mystery but it was probably a decision they made whilst banishing the Start menu from Windows 8.

I have talked about it in this blog – Good CRM design should not make users think

You have a couple of good options

CRM 2013 One Click solution

Use these Bookmarks to help speed your navigation

CRM Navigation Hacking with Bookmarks

Trusted Sites

This isn’t a problem but something you need to remember when setting up CRM for customers you need to make sure you add CRM to IE’s trusted sites

How to Add CRM to Trusted Sites

CRM is acting weird, option sets don’t work properly

If you are using IE, trying playing with compatibility mode settings on your browser

Configuring Settings for IE 10 and CRM 2011

The article only mentions CRM 2011 and I can’t remember if I had these problems in CRM 2013 but I thought I would put it here.

Any more?

If you have any more annoying things in CRM please add them in the comments

CRM 2015 – CRM developers should think in Entities

The humble Entity is one of core building blocks of CRM and CRM development.

  • CRM developers need to view the world as entities
  • You need to translate users work items to entities
  • Understand out of the box entities and custom entities

When CRM developers look at things they should see things in entities like the matrix picture.

When a customer tells you the requirements you should be thinking about it in entities

You are an entity called CRM Developer!

What is an Entity

Entities do a lot in CRM, to understand what they are and what they do I think it helps to view them in different ways

Customer

Entities are used to model the business data of the customer to accompany the out of the box entities which exist in the default CRM system (account, task, contact, business unit)

CRM Database point of view

  • Every entity in CRM is a table in the CRM database.
  • Every field on an entity is a column on the entity table.

CRM Dev point of view

Most entities have at least one form in CRM.

Customizations are organised (to some extent around entities) in your solutions

Task

CRM Developer Plugins

Plugins are triggered by actions on Entities (you can add multiple triggers on a plugin).  The messages (read actions on an entity) aer

  • Create
  • Update
  • Delete
  • Retrieve
  • Retrieve Multiple
  • Assign
  • Share
  • Associate
  • Dissociate
  • Set State

Entity Status

Entities have a status and status reason.  These values can be used to drive the entity through a process/life cycle.  To learn more about Status and Status reason read the blogs below

CRM 2013 – Understanding Status and Status Reason – think before deleting them

CRM 2015 – how to find Statecode value

Security

Security roles set access rights on entities – Create, Read, Write, Delete, Append, Append To, Assign, Share.

Entities can be owned by users/teams and these provide access levels such as none, user, business unit, child business unit, organisational.

security

Start with the CRM SDK

When learning about topics in CRM it’s good policy to start with the CRM SDK and find the truth about entities, find out what properties and methods entities have.  When I use the term CRM SDK I mean the CRM SDK documentation

Development for Microsoft Dynamics CRM Online and on-premises (CRM SDK)

You could also look at the CRM Developer Website, which I wrote a blog about recently

CRM Developer Centre gets updated and it looks good

Entity

Microsoft.Xrm.Sdk.Entity

What properties/members do you get with the Entity

Entity Properties

The Entity has a number of properties but here are the keys ones

Attributes

The attributes parameter holds a collection of all the fields in an Entity.  The atrributes collection works by holding fields which have a value.  If a field is null it isn’t included in the attributes collection (when you call from plugins).

You often need to check for a value in the Attributes collection using the contains method

entity.Attributes.Contains(“name”);

This will create lots of if statements with contains, if true retrieve the attribute type code.  You can work around this by using Entity.GetAttributeValue which will get the value if the field exists in the Attributes collection or return the default value for simple variables or null for complex variables.  Read more about it using the link below

CRM 2013 – using Entity.GetAttributeValue instead of Entity.Contains

LogicalName
Each Entity has it’s own individual name stored as a string.  The logical name is useful because sometimes in the code you will need to know what type of entity it is e.g.

task, account, phonecall, contact.

The LogicalName can be useful if you have plugin code which is triggered on a number of different entities.

Id

The all important Id of the entity record.  This holds the Guid.  This is important because when you retrieve any information you can use this ID to retrieve the individual Entity record and ask for particular fields of interest.

EntityState

Gets the state of the entity, useful

Entity Abstraction and Early binding

Good practise for CRM developers is to use Early binding which will create an Entities file and allow you to create Account, Contact, Task records.

Early binding strongly types the field values for an entity.  These values are the same fields you would find in the attributes collection on the Entity object.

  • What are the benefits of early binding
  • Readability
  • moving type errors into compile time and not run time (e.g. compile time = developers, runtime = testing or users)
  • reduce syntax errors

The easy way to make your Entities file is to use the CRM Early bound generator

CRM 2013 Tool – CRM Early Bound Generator

Whilst you are there don’t forget to make your optionset enums

CRM 2013 – Create Enumerations for option sets

What has the Entity got to do with Abstraction?

When you are using early bound classes in your CRM code you are then extending Entity object with the new early bound classes

Entity –> Account, Contact, Task, etc

Using Entity can be useful when creating common functions because all your early bound classes inherit from Entity.

The code below checks the entity (which is an Entity object) to check the name.  The code in the example could be either a Task or PhoneCall.  The Complete activity either sets a task to completed or a phonecall to made.


            if (entity.LogicalName.Equals(Task.EntityLogicalName))
            {
                CompleteActivity(activity.ToEntity<Task>());
            }
            else if (entity.LogicalName.Equals(PhoneCall.EntityLogicalName))
            {
                CompleteActivity(activity.ToEntity<PhoneCall>());
            }

It’s useful to remember all early bound entities inherit from Entity.

EntityReference – Entity’s little brother

The EntityReference object in CRM is a lookup to an Entity object.  An EntityReference has LogicalName and Id (guid) of the entity.

When ever you see a lookup in a CRM form you know this is an EntityReference with just enough detail for you to retrieve the Entity object.

There is a good code tip is you can get an Entity Reference from an Entity object

Hosk CRM Dev Tip – Get EntityReference from Entity

EntityReference entRef = entity.ToEntityReference();

When creating new lookups on your forms, it’s best practise to put ID on the end of the field name, so CRM developers can easily find the lookups

Hosk CRM Dev Tip – add ID suffix to lookup fields

 

CRM 2015 – how to find Statecode value

Someone asked me how to find the StateCode value on a custom entity today, so the first thing I did was to search the Hosk CRM Blog.

A lot of people get confused between Status Reason and State code, if you do then read this blog post

CRM 2013 – Understanding Status and Status Reason – think before deleting them

quick guide

  • StateCode = Status
    • controls if the record is active/inactive
  • StatusCode = Status Reason
    • Status reason is linked to the state and gives the ability to different status reasons to a status.

CRM Developers point of view

Status and Status reason are both optionsets.  Option set have an int value and a text value.  The text value is meta data and the int value is held in the database on the database field.

Default entities have two status values

State

  • Active = 0
  • Inactive = 1

Status reason have different default values

Status Reason

  • Active = 1
  • Inactive = 2

Out of the box entities State and Status Reason

Out of the box entities can (and often do) have more than two Status Reasons where as custom entities can only have two States.  Microsoft often bend the rules for the default entities because they have created functionality which needs the default entities to behave in a certain way.
It’s useful to know how custom entities work so you can then appreciate how the default entities work and have been changed.  This knowledge will help you work on the default entities because you can take advantage of the added functionality and extra status values.
Below are two examples of the extra status’s for default entities
E.g. Case/Incident
  • Active
  • Cancelled
  • Closed

Lead

  • 0 : Open
  • 1 : Qualified
  • 2 : Disqualified
You can see the full list of default entities and their Status and status reasons
Looking at the list gives you an insight to the number of default entities which make up the out of the box CRM functionality.  It will give you an idea of how each entity works and the flow of it.

State and Status reason have different default values

The key piece of information is State and Status Reason have different values and this can be confusing, usually it goes down the lines of

I know State or Status Reason Active = 0 but which one is it.

A quick way to confirm what the Status or Status reason is, is to do an advanced find and use Status or Status Reason in a conditional.  If you then click the download Fetch XML button you can see the values being used

Status active 1
Status active 2
So you know Active Status (statecode) have the value of 0

No Magic Numbers

Magic numbers in development is when developers use number values for status or any option sets but give no indication what the values mean.  This makes reading/understanding the code difficult and extremely frustrating because you often have to go and look up the values.

Wiki gives a good description of Magic numbers in code

here is a good explanation on stackoverflow – What is a magic number, and why is it bad?

Below you can see an example of magic number being used in code, what status is number 6!  If you are lucky the developer will add a comment

if (incident.StatusCode.Equals(6))
{
//do something incident cancelled
}
The use of Option set enums makes this much easier to understand.  I believe code should be self documenting through the use of well named variables, methods and classes.
if (incident.StatusCode.Equals(incident_statuscode.Canceled))
{

//do something incident cancelled

}

Don’t be lazy, create the Option Set enums and make your CRM code more readable.  I have written a blog on why you should create Enumerations for optionsets.

CRM 2013 – Create Enumerations for option sets

There is a great tool to help you called

CRM Early Bound Generator

I reviewed the tool in the link below

CRM 2013 Tool – CRM Early Bound Generator