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 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

CRM 2015 – Understanding the plugin profiler and a puzzling error

I am a big fan of debugging my plugins using the plugin profiler, it’s easy, quick and you can do it on your own computer without adversely affecting any fellow developers

The alternative for debugging plugins is to debug on the server, I usually don’t like doing this because if the plugin is not in the sandbox is can stop the whole server and I have personally found remote debugging doesn’t always work with the debugger dropping off after 30 seconds.

Puzzling problem with the plugin profiler

Recently a CRM developer was debugging using the plugin profiler and he had a puzzling problem

He was creating a plugin which fired on post event of creating  which when a new entity was created, it created a Task, which referenced the newly created entity.

Here is a brief description of what the code was doing

  • created a new task
  • update the description on the task
  • set the Regarding to be an entity reference to the newly created Entity

The code was erroring, the CRM developer was puzzled.

This problem is what I would call a CRM riddle and to get to the answer you need to do a bit of thinking.

When you are investigating a bug you need to reject your prejudices and biases.  You probably have an idea of the cause of the problem and it’s fine to check this first but if it isn’t the cause you need to make sure you are systematic and logical in your investigating.

I have written a blog post recently where I have investigated a bug, you need to investigate bugs like Sherlock holmes looking for clues – Sherlock Hosk and the case of the annoying bug

When debugging, eliminate what isn’t causing the problem and whatever code or customization is left must be the culprit. – Sherlock Hosk 

When testing your code I alway feel it’s just as valuable to find out what isn’t causing the problem because you are narrowing down the list of potential causes for the bug.

This highlights the process you should use, methodological, changing one variable at a time.

In the article Why all developers should be friends with a cardboard developer,  I suggest, you get the cardboard developer to stand next to you.

  • You have stepped back from the problem, you have stopped to think
  • Go through step by step
  • Explain what you want to happen
  • Explain what is happening

For debugging I would add these points

  • change one variable
  • Test to see if problem is resolved
  • repeat

A mistake a lot of CRM developers make when testing for a bug is changing lots of variables and then not knowing what change has resolved the problem. If you do this you are now in a pickle because it means you have to change all the variables again or get the customer to change all of the variables to resolve the problem.  The other choice is you test again, changing one variable at a time.

Understanding the plugin profiler

To understand the problem you need to understand how the plugin profiler works.

Here is a good step by step guide

Debugging online plugin in CRM 2013

When you turn on profiling the profiler works by capturing all the data being sent and serializing it all into a file and then throwing an error.

This is why you see the error message

#exception (Recommended)

When the profiled component is triggered, an exception will be thrown with the compressed profile in the error message

Below is a picture from the step by step guide above

This is really like adding some code at the end of your plugin throws a InvalidPlugInExecutionException, which would roll back the transaction and not save those changes to the CRM database.  (I’m not sure it does throw an InvalidPluginExecutionException but I am saying it acts as if it does)

This allows you to keep running the test without the plugin creating/updating any records in CRM.  It means you can trigger the plugin multiple times.

Back to the Problem

We know when using the Plugin profiler to debug records don’t get updated or created.

This plugin was being triggered on the create message of a record. Let’s say it was the contact record.

The user put in the contact details, pressed save to create the contact record. This action was captured by the plugin profiler and saved to a serialized file with the InvalidPlugInExecutionException so the record was not being created.

The CRM developer was stepping through the code using the plugin profiler.  The plugin was creating a task, the next step tried to set the regarding to the newly created record.

The problem was being caused by the plugin profiler.  The CRM Developer was running the code in the plugin profiler the on the create of the contact record, the code was creating a new task record and attempting to set the regarding on the task to the newly created contact record but it was throwing an error because the contact record didn’t exist.

When the CRM developer turned off the plugin profiler the code worked fine but this left him confused for a while.

Understanding the how CRM works is important

I am often saying in blog posts

Always start with the CRM SDK

When I say this I mean CRM Developers should first look in the CRM SDK to see if they can understand how this part of the system is working, try to understand the underlying logic of CRM.

Most developers find example code by taking the easy option and searching the internet, finding a code example which someone has written, copying and modifying and using it.

The problem with this is you don’t learn how or why the code works and the CRM developer will not understand the process behind the code.

When you try to create the code yourself, you will experience lots of small errors but overcome them.

CRM Developers first find out how things don’t work to understand how CRM customizations do work – Hosk

In my blog post CRM 2013 – How to get guid of initiating record in CustomWorkflow

I couldn’t work out how to get guid of the initiating record of a custom workflow.  The reason for this was the plugin context passes in a target field and this has the initiating entity.

Custom workflows do not have a target instead they have PrimaryEntityId.

I found out this information by looking in the CRM SDK and thinking about the problem.

The puzzling plugin profiler problem puzzled the CRM developer enough to ask me what was going on, why did it work when the CRM developer stopped using the plugin profiler?

It’s important to understand how CRM works because when things go wrong and errors start popping up, this is when understanding how CRM customizations work will help you work out what the problem is but if you haven’t stopped to learn how things work then they will continue to be a mystery and resolving the errors will be very difficult.

What does the CRM SDK say

if you search the CRM SDK for plugin profiler you will probably get to this page

Analyze plug-in performance

This is a great page with lots of information, below is an excellent description of how the plugin profiler replay works

Replaying plug-in execution does not require a connection to a Microsoft Dynamics CRM server and organization. The advantage of this method is that you can obtain the plug-in execution profile from a customer and debug the plug-in remotely. A restriction of the replay feature is that you cannot change the sequence of calls your plug-in code makes in the debugger while you are debugging.

The replay feature provides the plug-in with a snapshot of the call data and event execution context from the Microsoft Dynamics CRM server. You are getting the same events, GUIDs, and so on from calls to the Organization service but no data is being modified on the server as you debug the plug-in. During the debugging procedure in the previous section, the plug-in actually connects to the server and makes calls in real time.

Whenever I read the CRM SDK I always learn something new, here is what I learned from the paragraphs above

  • The plugin profiler doesn’t need a CRM connection to work
  • You can profile on a customer production system and debug remotely
  • You get a snapshot of the data -same events and same guids
  • No data is being modified

Why the advanced find is a CRM Developers best friend

Microsoft caused quite a bit of unrest when they released CRM 2013, suddenly making the Advanced find button difficult to find, if you are interested I wrote about that in this post – Good CRM design should not make users think

In this post I want to write why I love the advanced find functionality in Microsoft Dynamics CRM.

I view the CRM Advanced find as an awesome swiss army knife

To new users and inexperienced CRM developers it looks like a simple tool to search the records in CRM.

To an experienced CRM developer it’s one of the key weapons in the CRM Developers armoury which when used correctly can save you loads of time and make your life a whole lot easier.

It can speed up navigation, help you create queries for your plugins, export and enrich data and even help you fix bugs.  In some cases when being brought onto an existing product, I have used the advanced find to go directly to records of a certain type because I didn’t know where to look in the CRM system.

What is advanced find?

Advanced find is a tool which allows you to create queries against the CRM database.  It allows you to select the fields you want to see in the results and filter the query with conditions.

You can then save this advanced find query as a personal view

The Advanced find is a lot more than just a tool to query CRM because in many situations it can

  • Save you time
  • help you understand
  • view field values and related entity field values
  • speed navigation

The reason CRM Advanced find is so useful (and why users and CRM developers were annoyed when Microsoft made it hard to find) is CRM is really one big database full of useful data.  The CRM GUI

  • view the data using a web browser
  • validate the data input
  • organise the data into forms etc
  • Add security
  • organise using the data
  • Development to automate adding/viewing data

The CRM GUI (website) has lots of functionality for validating and displaying the data.  This is really useful but for CRM Developers they often want to navigate the system quickly and are not interested in the GUI and business logic but just want to get to certain records.

The advanced find lets you search all the records in your CRM database and apply a filter condition to allow you to only bring back the records you are interested in.

One important consideration to remember when using the advanced find is it does apply your security profile, so you will only see what records your security profile has privileges to see.

Quickly find the records you need

The beauty of advanced find is it can bypass most the GUI and get to the record you want you want with a couple of clicks.

It can also bring back groups of records you want, which is more difficult to do with the front end GUI

The great thing is you can save the advanced find into a view so you can repeat the process even quicker next time.

When you don’t know the business logic

In some projects a CRM developer can be brought into the project in the bug fixing phase. It can be difficult to fix bugs when you don’t understand the business logic or how the system works.

Using the advanced find can help you easily navigate to the entity records you are interested because with the advanced find you can view all the entities in alphabetical order.

This can help you if the bug exists on a specific record type and you don’t need to understand the business logic, e.g.

  • Javascript form errors
  • Simple plugin triggering on update

FetchXML is a great place to create your query

When I have to create a query in a plugin, I usually start with an advanced find to get the logic correct.

You can then download the FetchXML and you can see which fields you need to use and how the filters should be structured

You can use FetchXML in Javascript

You can use fetchXML’s directly in your javascript. I usually use OData queries and the odata query tool.   One of the limitations of OData is it doesn’t have a distinct attribute, so there is no way to not retrieve duplicate records.

The query I was interested in doing needed to filter out the duplicates so I did it in FetchXML.  When I didn’t filtered out duplicates (the OData query) it was returning 1500 records, which slowed down the form load but when I used FetchXML with distinct set to true, it returned 25 records.

FetchXML directly in plugins

You can run FetxchXML code directly in your CRM plugins instead of query CRM using  Linq or QueryExpression.

I go through the process in the blog post below

 Build Queries with FetchXML instead of QueryExpression

One of the advantages of using FetchXML in a plugin is you can create the query in Advanced find which can sometimes be easier

Create saved views

Saved views can save you lots of time because you are only viewing the records you are interested in and filtering out all the other entities.

Export data

Using the Advanced find to select not only the records you are interested in but also the fields is very useful.

Being able to export these records and send them to someone who doesn’t have access to CRM is a very handy trick to customers.

Exporting the data will also allow you to move the data between CRM organisations and environments (e.g. Dev, Test, Prod)

Enrich Data – e.g. export, change, import

The good old Enrich data functionality, which is has the good, the bad and the ugly all in one.  It’s called Enrich the data but what it really means is you can export some records and when you import them it will automatically know which records to update.

enrich data

The enriching data functionality works by adding the Guid of the records to the export file (and some checksum columns etc) which are read by CRM when you re-import the data.  If it sees the values it knows you are not importing new data by updating/enriching existing data.

Bulk Edit

Once you have a list of the entities you are interested in, it’s easy to bulk edit those records and assign them all the values.

Bulk editing data in this way can add data which bypasses some of the validation in the GUI forms.  The reason for this is business rules and Javascript do not run because they are only triggered on the CRM form.

Understanding Plugin sandbox mode

Plugins

Plugins in CRM are great ways to run powerful .NET code and our one of the CRM Developers most powerful tools in his toolbox.

There are lots of steps you need to go through when creating a plugin and there are lots of things which can error.

The knowledge you need is usually built up with a bit of theoretical knowledge and then a lot of practical trying.  The amount of knowledge you need to write a plugin is one of the reasons Why .NET developers struggle with CRM Development

If you are starting out writing plugins, I would recommend my youtube plugin playlist

I would recommend reading my blog post on common plugin errors, which you will certainly experience at some point CRM 2011/2013 – Common Plugin Errors and Isolation Mode

The common errors talks about the  post discusses a deployment common error you might experience, which is you cannot deploy plugins with isolation mode = none if you are not a deployment administrator.

If the isolation mode = “Sandbox” then any CRM Developer who has the security role of Administrator can deploy plugins into a sandboxed environment.

Where can you see the Isolation mode of a plugin

When you create a plugin you can choose two different types of isolation mode

  • Sandbox
  • None

You may have seen these when you are deploying plugins in the CRM Developer toolkit, it’s in the RegisterFile.crmregister file, you can see each assembly has

IsolationMode= “Sandbox”

You can also see what isolation mode of a plugin if you open the Plugin Registration Tool.

  1. open the Plugin Registration tool
  2. connect to CRM instance
  3. Right click on an Assembly and choose update
  4. Now see the Isolation mode

isolation mode

Confusion

When developers talk, naming and terms used can add confusion and slow down people’s understanding.

A plugin assembly has a setting called Isolation mode and this can be set to None or Sandboxed, but you will rarely hear any CRM developers use the term isolation mode.

Instead they will say things like these

  • A plugin is sandboxed
  • CRM online plugins must run in the sandbox
  • it’s a normal plugin

When a CRM Developer mention Sandbox/Sandboxed and plugin they mean the plugin has an isolation mode which equal “Sandbox”

CRM online plugins can only run with an isolation mode = sandboxed

A normal plugin is a plugin which has an isolation mode =  “none”

Often used but not really understood

CRM isolation mode is used all the time by all CRM developers who create plugins but often most CRM developers only have a vague idea of what Isolation mode means.

Most CRM Developers will have heard about Isolation mode with regards to CRM online.  The reason for this is CRM Plugins created for CRM Online organisations must have Isolation mode = “Sandboxed”

What is the Isolation mode?

The first (and best) place to start with understanding Isolation mode and Sandboxed plugins is with this great MSDN article which can be found in the CRM SDK (which should be the first place you look for documentation)

Plug-in isolation, trusts, and statistics

You will notice the isolation mode of a plugin is at the assembly level and not the individual plugin level.

This is why when you create a new plugin there is no setting for isolation mode because it’s at a DLL\project level and you can have many plugins inside one project (or inside one dll).

Isolation Environment

Plugins with an isolation level of “Sandbox” run in an isolated environment and as you can imagine this environment is more secure.  Key point

The sandbox is more secure and some actions are restricted

The restrictions are a bit of mystery, in the sense there is not one all encompassing list of code which will cause an error in a sandboxed plugin.  This can be very frustrating when you deploy a plugin in the sandbox and it throws an error, finding the cause of this can be difficult and frustrating.

The Plug-in isolation, trusts, and statistics article states

isolated environment, also known as a sandbox, a plug-in or custom activity can make use of the full power of the Microsoft Dynamics CRM SDK to access the organization web service. Access to the file system, system event log, certain network protocols, registry, and more is prevented in the sandbox.

The article gives a good description of what this means by saying Plugins deployed in the sandbox are partially trusted (e.g. you only partially trust the plugin and are limiting it’s powers) and plugins which are not in the sandboxed are fully trusted (by you the developer) and you are happy to let them interact with the file system, registry, call other dll’s and web services etc.

Sandboxed and non sandboxed plugins

I recently had some experience with sandboxed plugins because a project I was working on moved all the plugins out of the sandbox.  The first result was I couldn’t not update or publish any plugins because I wasn’t a Deployment admin

The second side effect is I remember the sandbox has its own service.  If you have ever installed CRM you notice there are Sandbox CRM Service and standard CRM Service.  Most CRM Developers know of the services when they do one of the many IISRESETS + Service restart, which usually happens if you have DLL’s in the GAC.  The sandbox service runs all the sandbox plugins.

The sandbox service runs all the sandbox plugins.

I was remote debugging, so instead of attaching the remote debugging to the

  • w3wp.exe – standard plugin
  • CRMASyncService.exe – if the plugin is asynchronous
  • Microsoft.Crm.Sandbox.WorkerProcess.exe – for sandbox plugins

One reason I personally don’t like remote debugging is if someone is debugging a standard plugin, then by debugging the w3wp they stop the whole server whilst and everyone else who is using it.  I have seen some scenarios where other developers and testers have had to stop whilst the one developer debugged his plugin (poor show).

To get around this you can change the plugin to sandboxed and then when you debug you only stop the sandbox service

Sandbox limitations

I have stated previously it’s difficult to know what the limitations are but here some of the limitations taken from the msdn article

  • Access to the file system (C Drive)
  • system event log
  • certain network protocols
  • registry
  • You cannot access any other DLL’s
  • IP addresses cannot be used
  •  Only the HTTP and HTTPS protocols are allowed.
  • In isolated mode you cannot call any external DLL’s\DLL’s in the GAC

This blog had some good restrictions in a bit more detail

  • Attempting to use the AppDomain.CurrentDomain.AssemblyResolve event
  • IO.Path.GetTempPath() [System.Security.Permissions.EnvironmentPermissionException]
  • Any filesystem access code [System.Security.Permissions.FileIOPermissionException]
  • Attempting to use the EventLog [System.Diagnostics.EventLogPermissionException]
  • Attempting to use IsolatedStorage [System.Security.Permissions.IsolatedStoragePermissionException]
  • Any references to Thread.CurrentThread caused a security failure.

Someone tweeted me a great article on security and sandboxed plugins

How to: Run Partially Trusted Code in a Sandbox

The article is fantastic but it does highlight the difficulty developers can experience using the CRM SDK, sometimes the information is there but it’s hard to find.

CRM Online limitations

I believe CRM online sandboxed plugins cannot use LINQ queries, which throws an error due to another transaction being created in the LINQ query.

Custom workflows cannot be used in the CRM online sandbox

Correction – You can call WCF webservices 

I originally put you couldn’t call webservices but I have been corrected thanks to a great comment from Andrii Butenko

To use webservices all you need is to use WebClient if possible like https://msdn.microsoft.com/en-us/library/gg509030.aspx

In case only WCF is available you can call it but you have to manually build binding https://mscrmmindfire.wordpress.com/2013/06/14/calling-external-web-service-from-a-crm-2011-plug-in/

CRM 2015 Online allows custom workflows

Another great comment has caused me to update this post.

Custom workflow activities can now be registered in isolation mode in CRM 2015 online

https://msdn.microsoft.com/en-us/library/gg334752.aspx

Example error

I came across an error which prompted me to write this blog post.  I was trying to serialize some fields and pass them between plugins using shared variables

This forum post below is the same error

https://social.microsoft.com/Forums/en-US/9ce3c4e6-0587-4913-89f8-f3942d7bac93/using-systemwebextensions-in-crm-plugin

Unhandled Exception:

System.MethodAccessException: Attempt by security transparent method ‘TestingSeam.CrmTesting.Execute(System.IServiceProvider)’ to access security critical method ‘System.Web.Script.Serialization.JavaScriptSerializer..ctor(

This error was unusual because it was complaining about access to a critical method.  I wondered why serialization was critical method but thinking about it, serialization must involve writing the data to disk and sandboxed plugins are not allowed to do this.

A Gotcha also occurred when someone changed the plugin to sandbox mode, it stopped the plugin working, so I had to leave a comment in the code to say, this plugin won’t work if the plugin is sandboxed.

Why put plugins in the sandbox

So the question is why would people choose to put plugins in the sandbox.

The most common reason is they are using CRM online and you have no choice because all plugins have to be

Runtime statistics are created  PluginTypeStatistic entity records. These records are populated within 30 minutes to one hour after the sandboxed custom code executes

https://msdn.microsoft.com/en-us/library/gg334752.aspx

This url has an interesting benefit

  1. If the sandbox worker process that hosts this custom code exceeds threshold CPU, memory, or handle limits or is otherwise unresponsive, that process will be killed by the platform. At that point any currently executing plug-in or custom workflow activity in that worker process will fail with exceptions. However, the next time that the plug-in or custom workflow activity is executed it will run normally. There is one worker process per organization so failures in one organization will not affect another organization.

Why haven’t you listed all errors

Some readers maybe dissapointed I haven’t listed all the methods and exact lines of code which will cause sandbox plugins to throw security errors.

Whilst writing this blog post I realised the reason Microsoft have listed all the causes of security errors in sandboxed plugins because there are potentially lots of them and if they tried to list them all, they would miss some. In fact I would say it’s impossible to list them all, so there is no benefit to trying.

The way to think about the sandbox is it’s a bit like a sandpit and the code is a child.  As soon as any code/child tries to get out of the sandpit we throw an error and a parent comes along, tells the child off and throws them back in the sandpit.

This is why sandboxed code is safer because it can’t get onto your server and cause havoc.

Summary

The limitations of sandboxed plugins can be a significant influencing factor for many CRM solutions to be on premise.

The limitation of not being able to call webservices and DLL’s in the GAC can be quite restrictive.

There is a solution using ILMERGE, which is a method of merging a number of different DLL’s into one DLL, which will allow you to use the plugin in a sandboxed environment.  I would be cautious about this approach because if you ask anyone who has done it, they will tell you it wasn’t easy and debugging a merged DLL can be impossible.

Here is a good article on ILMerge issues

Why .NET developers struggle with CRM Development

Experience is important for a CRM Developers. You have to learn how things don’t work first 🙂 no shortcuts

CRM Developers have to learn the mysterious ways of CRM development, they need to learn the the quirks and the way things work with Microsoft Dynamics CRM development.

Microsoft Dynamics CRM can be illogical but we are all used it to now.

If CRM was an animal I think it would be a cat, it’s unpreditable and sometimes very difficult to persuade it to do as you would like

CRM

This makes experience very important because to learn how things work, you have to go through the process of things not working (often in many different flavours of not working) before it works

There are some shortcuts but often you have to go through the painful process yourself.

LIKE WHAT

 

Plugins

When a CRM developer starts developing a plugin, he will learn the all the steps you need to take and the hoops you need to jump through

I went through some of the common problems in this blog but here is a quick recap

  • setup up CRM Developer toolkit
  • User has to be CRM Admin
  • Isolation mode? if none user has to be a deployment administrator
  • plugin needs to be signed
  • crmRegister file needs to be checked out

These are the simple things you need to do to create and register a plugin, that’s without even thinking about the code and if it works, testing, debugging etc.

CRM tools

There are lots of tools where you have to put the server, the CRM Discovery URL, the OganisationService url.

At first you guess what they are, fail a bunch of times until you knuckle down and find out where those urls are, what they do and why the tool needs them.

Use Microsoft Dynamics CRM services in code

Then one day you find they are hidden in CRM under settings, developer resources!

CRM 2011 – Discovery and organization service are held in settings

WHY .NET/C# struggle developing

Sometimes companies don’t want to pay for CRM developer or have C# resources which they think they will use to do some CRM plugin customization.

This theory seems like a sound idea, the actual C# code in a plugin is usually quite small and not overly complex but for a C# Developer with no CRM experience it’s a total nightmare

C# developers with no Microsoft Dynamics CRM development experience don’t understand how data in the CRM website is structured in SQL Server database

  • How CRM works with customizations
  • The different types of customizations to choose from, without this knowledge how do you pick the correct customization type.
  • How do I create a plugin
  • How do you register a plugin – common plugin errors
  • How do I write a query to retrieve related records in CRM

Whilst the C# developer goes through learning how things don’t work, it takes the developer a lot longer to write the plugin (if they manage it)

The kicker is if they don’t do constant CRM Development, they will forgot all the lessons they learnt from the work above, slide down the snake and have to learn all again next time.

Hands on experience is vital

The reason hand’s on experience is vital for CRM developers is when a CRM developer is creating customizations and code to work, they will have to overcome a lot of situations where the code isn’t compiling, it isn’t working.  During this minor setbacks you the CRM developers will read blogs, the SDK and work out why it doesn’t work.

The CRM developer will end up with a working customization, e.g. plugin but will also have a better understanding of creating CRM customizations and a more in depth knowledge of how the CRM customization works.

You cannot get this knowledge and experience through reading about CRM customizations like plugins, custom workflows etc.

Creating the customization gives you a deeper knowledge of CRM development because reading about CRM development won’t tell you about what doesn’t work.

If you think about knowledge as 3 dimensional object, reading about CRM Development gives you one view of the object.  Getting it working and overcoming the errors during this process gives you a different view of the object.

Experience is earned

When you start creating CRM plugins, worfklows and other customizations you will run into lots of puzzling problems.  Slowly one by one you will overcome the initial problems and find more intricate problems, which usually move towards logical problems and quirks particular to CRM development.

e.g.

The point I am trying to make is CRM Developers learn CRM development by overcoming errors and problems and learning not to make them in the future.

The CRM developer will make less errors whilst creating their CRM customizations (plugins, custom workflows, Javascript, etc), this gives them time to focus on refactoring their code, new functionality, testing, writing better structured code (which is readable).  Their understanding of the underlying CRM structure grows and becomes more in depth.

I view CRM developer progression similar to driving a car.  When you start out driving a car, everything is difficult and you have to think and remind yourself to do these tasks

  • Putting on your seatbelt
  • Seat right positioned correctly
  • Constantly checking all of your mirrors
  • Indicating at the correct time
  • Changing gears and being in the right gear
  • Braking distance
  • Estimate distance
  • Monitoring speed (and not speeding)
  • Understanding what the road signs mean

The driver slowly gets more experienced and begins to do many of the those tasks without thinking, this gives them time to focus on other parts of driving, like not crashing and watching out for idiots on the road.  Driving on the motorway, driving in the rain and snow are all experiences built up over time.  Slowly the driver will become better (hopefully).

The point is you can’t read how to become a better driver, you have to apply the knowledge and experience it yourself.  The same is true about CRM development.

The only way to speed up experience is to do some CRM development outside of work.

Example

Mark McGookin had been working on some CRM development and getting IFrame errors.  Errors messages rarely point to the actual problem as most CRM developer find out.  Error messages are a sign something went wrong and you need to do some detective work to find the root cause.  You can do this by checking your logging, Plugin Trace files, Event Viewer on the CRM server or by debugging the customization.

 

Mark was trying to use Document Management in his code, eventually he found the iFrame error was actually occurring because the SP Root location was null.

crm dev experience

Summary

Experienced CRM developers make less errors because they have learnt to stop making these errors through experience and bug fixing those problems.

Due to the experience and knowledge gained through experience and reading they will make better choices about what customizations work well in certain scenarios

One the key roles experience developers have is advising and peer reviewing less experienced developers.  Finding problems and bugs earlier in the process can save you hours if those same bugs are found when the CRM customization has gone to the customer.