1 . To Multi-Tenant, or Not To Multi-tenant?

Answer :

If you're talking about 10 branches, multi-tenancy seems like a big cost with little benefit.

There are complications with multi-tenancy you don't mention:

  • Versioning becomes difficult. Clients X, Y, and Z may want a new feature while clients A, B, and C don't. A multi-tenant app makes accommodating everyone difficult, especially if a new feature requires database schema changes. It's not impossible, it's just more difficult.
  • Some clients are very uncomfortable with their data mingling in the same tables as other clients. Even though we know better, it feels like a security risk to them. Legal departments hate it. In addition, if you ever dump raw data for a client, a shared database requires caution.

You can eliminate a few of your pain points with better practices:

  • Automate deployment. This should make it easier to add a new client or upgrade/downgrade an existing client. Database maintenance (backups, rebuilding indexes) should be set up automatically as well.
  • Store shared data (SKUs, inventory) in a central database and have every application instance access it either directly or through a service.

Don't get me wrong, one of the more interesting apps I worked on was multi-tenant. There can be huge benefits, but you'll more likely see them with thousands of clients versus ten.

Leave a Comment

1 . Compiling single C# project to multiple DLLs?

Answer :

I don't think you can do this directly in Visual Studio, but, if you manually invoke the compiler in a script or makefile, it should be pretty straightforward.

For example, csc /t:library /out:MyCodeLibrary.dll simpleType.cs compiles simpleType.cs to MyCodeLibrary.dll.

You could run this as a post build step, to generate the assemblies you want. However, just be careful that whoever is using the project understands what is going on... most developers would expect a single project to produce a single dll.

2 . Start workflow with javascript in Dynamics CRM 2016?

Answer :

Now that we have actions there really isn't a need to start a workflow from javascript anymore. I used to do so using a javascript library that used the SOAP api but the web api actions are much easier to use. And an action is created in the same way as a workflow. To create an action go to create a workflow but instead of choosing workflow from the dropdown select action. You will end up with a form like this. enter image description hereRemember the unique name and the entity which you will run it against. In this example I'll be using this workflow pictured which runs against a contact record. From javascript I can now issue a POST to


Again this is an action targeting contacts and running the wa_GetContactSyncStatus action, change the values to what you need them to be. Also as a side note this is against a 2016 server anything later will have a different api version for you to use. Consult the developer resources page in your crm instance to figure out what your url for the web api is.

The action will run asynchronously and as long as your javascript request is set to be synchronous as well your request will return when the action is complete.

As another side note if you have your action call another workflow that isn't synchronous it will quite probably return before your asynchronous background workflow does.

3 . CRM 2011 update incident when email arrives?

Answer :

I've just been fighting with this exact same issue and came across this post. I thought I'd post the solution for you (if you still need it) and anyone else who comes across the issue in the future.

Here's the solution I arrived at: - Using the Plugin Registration Tool register a New Image on the appropriate step( Stage = "40", MessageName = "DeliverIncoming") - Set the New Image to be a Post Image - In your plugin fetch the Post Image's entity ID:

Guid emailID = context.PostEntityImages["PostImage"].Id;
Entity emailFromRetrieve = localContext.OrganizationService.Retrieve(
    new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
Email email = emailFromRetrieve.ToEntity<Email>();

if (email.RegardingObjectId == null)

var regardingObject = email.RegardingObjectId;

4 . Multiple Developers + Single Dynamics CRM Instance + Git - How to overcome challenges?

Answer :

I feel this is one those areas where CRM still makes life difficult, and provides only limited tooling and support.

In my experience, its just easiest and most practical for everyone to do all their customistaion and configuration work in CRM, and forgot about 'normal' source control. Having to import and export solution files can be a very slow process which will drive you mad. Editing solution files outside of CRM is a mine field you will want to avoid. When working on a single CRM instance no merging is required, as everyone can immediately see each others changes. In my experience generally this process will just add overhead which can normally be avoided.

Doing an export to source control regularly (e.g. middle of the night) is still sensible so you have a backup if things go wrong.

You can also still source control all your source code normally, e.g. plugin code.

Also the example you noted above involves the developers working on multiple CRM instances (e.g. each developer has their own CRM development instance), not a single CRM instance as you mention.

5 . Error in FetchXML report since Dynamics 365?

Answer :

I don't know of any changes to 365 that should break this. However, what I would do to fix it is create a report using the wizard that uses this same entity. Download that report and check the following:

  • Data Source - Are there any slight differences in Data Source name and/or connection string?
  • Data Set - Are there any subtle differences in the FetchXML from casing to versions etc?

That should point out the problem. If not, and that downloaded report works, either just copy in the attributes etc you need into the new report and go with that instead (it might be some xml within the report itself). Or if your report has nothing on it you could start comparing the raw xml of the 2 reports to see what is different.

6 . CRM 2011 List component for SharePoint - customise column widths?

Answer :

Well you have limited options here. Because you're dealing with multiple domains, you run into cross domain scripting issues ruling out any javascript on the crm form.

The only way that comes to mind is to modify the crmgridpage.aspx page on your sharepoint server to set the width of the columns via javascript. It's totally unsupported though.

7 . C# read timezone from string and convert to local?

Answer :

Save them as universal time:

   DateTime t = DateTime.Parse(str);
   t.ToUniversalTime(); // save this

Then show saved time as local:

   DateTime t = DateTime.Parse(str);
   t.ToLocalTime(); // show this

Always work with universal time, think about local as just a view in mvc.

8 . Cannot receive RemoteExecutionContext messages sent from CRM to Service Bus Queue in Azure Biztalk Service?

Answer :

As it turns out I totally missed to limitation that Azure Biztalk Services cannot receive binary messages - even if you try to PassThrough them and try to serialize them in a custom step.

My solution will be to compose a Xml message to send to Azure Service Bus Queue in a custom Plugin without using Service Endpoint registration provided by MS CRM.

Update 2016 Update 1 will allow to configure the message format and support binary, xml and json formatted messages form the Service Endpoint Registration. See Walkthrough: Configure Microsoft Azure (SAS) for integration with Dynamics CRM for details. Note the differences in the configuration dialog to previous versions.

9 . Debugging into a javascript anonymous function?

Answer :

Older version of IE is pretty lame specially when it comes to debugging AJAX applications. Firebug is the best that I have seen. It lets you replace an existing javascript function with your own. This is what I suggest.

  1. Open the web application in Firefox
  2. Copy sourcecode of existing function
  3. Format it and add the following statement to the function at the place where you want it to stop and inspect the variables.
  4. debugger;

10 . How can I get Microsoft Dynamics 365 to appear in the list of data sources when creating a report in Visual Studio 2017?

Answer :

At the moment VS 2017 is not supported. Here is quote from Dynamics 365 Report Authoring extension software requirements:

Microsoft Visual Studio 2015, Microsoft Visual Studio 2013, Microsoft Visual Studio 2012, or Microsoft Visual Studio 2010.

So the only way out for you is to install VS 2015/2013/2012/2010. Good luck.

11 . Could not load file or assembly 'Microsoft.Xrm.Client?

Answer :

Microsoft.XRM.Client is usually not needed by the plug-in.
It is needed to connect to CRM from an outside application.
Microsoft.XRM.Client has been removed from the SDK since CRM 2016.

Plugins do not automatically resolve dependencies in your project, they have to already be on the server. 

Update for Dynamics CRM 2015
The NuGet package Microsoft.CrmSdk.Extensions contains Microsoft.Xrm.Client.

Update for Dynamics CRM 2016 and Dynamics 365
Microsoft.Xrm.Client is no longer part of the SDK.
The NuGet package Microsoft.CrmSdk.CoreAssemblies contains everything needed for plugin development.

The various parts of the Dynamics CRM SDK are in NuGet.
NuGet is a much better solution than adding Dynamics CRM dlls as project references; especially for source control and team development.

12 . The transaction log for the database is full?

Answer :

To fix this problem, change Recovery Model to Simple then Shrink Files Log

1. Database Properties > Options > Recovery Model > Simple

2. Database Tasks > Shrink > Files > Log


Then check your db log file size at Database Properties > Files > Database Files > Path

To check full sql server log: open Log File Viewer at SSMS > Database > Management > SQL Server Logs > Current

13 . Trying to change owner of account on CRM 4.0 using a plugin?

Answer :

It had been staring directly at my face :P I was entering the wrong ID's at the wrong place. I needed to set the 'assignee.PrincipalId' to the 'ownerGuid' and then set the 'target.EntityId' to the current account id. The new code is as follows:

                TargetOwnedAccount target = new TargetOwnedAccount();

                SecurityPrincipal assignee = new SecurityPrincipal();
                assignee.Type = SecurityPrincipalType.User;
                assignee.PrincipalId = ownerGuid; //this is the GUID I am retrieving from the other lookup field

                target.EntityId = ((Key)entity.Properties["accountid"]).Value;

                AssignRequest assign = new AssignRequest();
                assign.Assignee = assignee;
                assign.Target = target;

                AssignResponse res = (AssignResponse)crmService.Execute(assign);

Cant believe i spent 8 hours yesterday looking at it and then today I realised immediately :P

14 . Dynamics CRM 2011: Managed Solutions or deploying changes from DEV to PRD?

Answer :

I would advise against using solutions in these type of dev-to-testing-to-prod situation.

If you are unsure about this try to remove an entity in your dev environment and publish the change to your production environment.

Solutions are inclusive meaning that CRM doesnt remove fields and entities that where deleted in your solution.

The only way to remove an entity is to uninstall your solution therefore deleting the production data in all entities covered by your solution!

While in theory solutions seem perfect they are only usefull for third party vendors.

The goal of beeing able to rollback by uninstalling your solution is a pipe dream. Consider a data model update that involves data conversion. No magic function will reverse that.

It is a far simpler and reliable to restore your backup.

15 . How to do a LINQ query for count of enitity whose owner == current user?

Answer :

I'm not sure your the data structure of LeadSet but i'd imagine something like:

context.LeadSet.Count(ls => ls.OwnerID == ownerId);

This above pulls the count of all leads where the OwnerId equals your parameter ownerId.

If you want the objects that match, just use .Where in place of .Count