CRM 2011: How to compare CRM fields with Linq

Well, you can’t. As Microsoft states here:

In a where clause, the left side of the clause must be an attribute name and the right side of the clause must be a value. You cannot set the left side to a constant. Both the sides of the clause cannot be constants.

So, you cannot do something like:

from a in context.AccountSet
where a.ModifiedOn.Value > a.CreatedOn.Value
select a.Name

Trying this will get you a nice and sweet error message explaining to you that:

InvalidOperationException: variable ‘<> […] referenced from scope ”, but it is not defined

So if you want to do it, you have to retrieve your data and filter it in memory using the Where extension method:

var resultsToFilter = (from a in context.AccountSet
select a.Name, a.ModifiedOn, a.CreatedOn)
.ToList();

var filteredResults = resultsToFilter
.Where(x => x.ModifiedOn.Value > a.CreatedOn.Value) ;

And there you have it.

 

Dynamics CRM and SPNs

Maybe you’ve already heard of SPNs, also known as Service Principal Names. Most CRM technical people have heard of them, but not many can really explain WHY they are necessary. Some can say it is for ensuring “mutual authentication”, but few can really explain how this mechanism works.

Today, let me explain to you my understanding of SPN’s, based on this article.

The Kerberos mechanism by which a client authenticates a service works as follows:

  • When a service is installed, a service installer, running with administrator privileges, registers one or more unique SPNs for each service instance.
  • The names are registered in the Active Directory Domain Controller (DC) on the user or computer account object that the service instance will use to log on.
  • When a client requests a connection to a service, it composes an SPN for a service instance, using known data or data provided by the user.
  • The client then uses the SSPI negotiate package to present the SPN to the Key Distribution Center (KDC) for the client domain account.
  • The KDC searches the forest for a user or computer account on which that SPN is registered.
  • If the SPN is registered on more than one account, the authentication fails.
  • Otherwise, the KDC encrypts a message using the password of the account on which the SPN was registered.
  • The KDC passes this encrypted message to the client, which in turn passes it to the service instance.
  • The service uses the SSPI negotiate package to decrypt the message, which it passes back to the client and on to the client’s KDC.
  • The KDC authenticates the service if the decrypted message matches its original message.

Let me rephrase this in the CRM world:

  • When CRM is installed, SPNs are registered for the identity of the application pool CRMAppPool. It can be Network Service or some other account.
    • That’s why, when changing the identity of the application pool, you need to remove existing SPNs and create new ones.
  • When a client requests a connection to CRM, it composes an SPN for it.
    • That’s why you need to register SPNs for both server the server name and the FQDN, because you can’t be sure how the SPN will be composed by the client.
  • (1) The client presents the SPN to the KDC for the client domain account
  • (2) The KDC searches the domain for a user or computer account on which that SPN is registered
    • Here, the KDC must find the identity of the CRMAppPool
  • If the SPN is registered on more than one account, the authentication will fail
    • Indeed, because the KDC will not know which account to use
  • The KDC encrypts a message with the password of the CRMAppPool identity
  • (3 & 4) The KDC passes the message to the client, which passes it to the service instance, ie to the CRM server
  • (5 & 6) The CRM server can decrypt the message, passes it back to the client which passes it back to the KDC

So that’s why we talk about mutual authentication: not only is the client identified (this aspect is not described here), but also the service.

Posting data from jquery ajax call to MVC4 controller: data posted is empty

Say you want to create a new contact from an ajax call and have somthing like that:


var theContact = {
lastname: 'Smith',
firstname: 'John'
};
var theData = JSON.stringify(theContact);
$.ajax({
type: "POST",
url: "/contacts/create",
contentType: "application/json; charset=utf-8",
data: theData,
dataType: "json",
success: managesuccess
});

Then on the server, you carefully create your Contact class and the controller, paying attention to giving property names that are identical on client and server:


public class Contact
{
public string lastname;
public string firstname;
}

[System.Web.Mvc.HttpPost]
public string Create(Contact newContact)
{
// Logic
}

Only to realize that while the data is correctly posted from the client, on the server newContact properties stay desperately empty. Well, stop tearing you hair out, all you have to do is to follow best practice and adapt your Contact class by adding get/set! Like this:


public class Contact
{
public string lastname { get; set; }
public string firstname { get; set; }
}

And your data gets correclty posted, what a relief…

Copying table from one sql server instance to another instance

I have added the remote server as a linked server in Management Studio to import data from that server into my local SQL Express instance.

Running the following query works fine for most tables:

Select * Into TheTable
From [LinkedServer].[RemoteDB].[dbo].[TheTable]

But a particular table containing spatial data, I received this error message:

Objects exposing columns with CLR types are not allowed in distributed queries. Please use a pass-through query to access remote object

To solve this problem I had to run the following query:

Select * Into TheTable
From Select * from openquery([LinkedServere], ‘select * from [RemoteDB].[dbo].[TheTable]’)

And it worked fine!

 

Error when adding a new MVC4 project to the solution

When trying to add a new MVC4 project to the solution, I received the following error message:

Cannot add the item because the item to add it to is not a solution folder or the solution

 

To fix this issue, go to tools/options, click Show all settings, and in projects and solutions, just check the “Always show solution” option. Now in the solution explorer, your project will appear under its parent solution. Then you will successfully add a new MVC4 project to the same solution.

Use SQL Express with your MVC4 Single Page Application

Currently playing with Visual Studio 2012 and MVC4, I’ll quickly share how to properly set up your membership provider to use SQL Server Express.

1. Install Visual Studio 11 beta

2. Install SQL Server Express 2012

3. Start Visual Studio, create a new project, select MVC4, then Single Page Application,

4. In SQL Server Management Studio, create a new database

5. Run aspnet_regsql.exe (in C:WindowsMicrosoft.NETFramework64v4.0.30319) and follow the steps. This will create the required tables in your new database to manage the different .Net providers (membership, profiles, roles, etc..).

6. In your application web.config, add a new connection string that points to your SQL Express. Should look like the following with SQL authentication:

<add name=”SQLExpressConnection” connectionString=”Data Source=.SQLExpress;Initial Catalog=mydatabase;User Id=sa;Password=password” providerName=”System.Data.SqlClient” />

And Windows authentication:

<add name=”SQLExpressConnection” connectionString=”Data Source=.SQLExpress;Initial Catalog=mydatabase;Integrated Security=true” providerName=”System.Data.SqlClient” />

7. Still in the web.config file, adapt the the DefaultMembershipProvider or add a new one in the <membership><providers> section. To actually have your application use your provider, make sure you set the defaultProdiver attribute of the mmbership node to the provider you want to use. Otherwise, the machine.config settings will be used. And make sure, in your provider, to set the connectionStringName to the connection string you defined above.

 

And you’re good to go!

The Plugin Profiler

I recently discovered the Dynamics CRM plugin profiler.

The Plug-in Profiler is a tool that profiles the execution of plug-ins for an enhanced debugging experience in Microsoft Visual Studio 2010. This tool, which can be run from the Command Prompt window or from within the Plug-in Registration tool, makes developing plug-ins against Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online quicker and easier. In addition, users can profile the execution of failing plug-ins and send the results to the plug-in developer or ISV for analysis. The developer can replay the plug-in execution and debug the plug-in remotely even when disconnected from the Microsoft Dynamics CRM server. The Plug-in Profiler is available in the 5.0.5 release and newer releases of the Microsoft Dynamics CRM SDK

The tool can be used in either the debug or replay mode. Each of these modes is described in the following sections.

1. Debug a Plug-in using the Plug-in Profiler

To debug a plug-in

  1. Build the Plug-in Registration tool according to the instructions in its Readme file. The tool can be found in the ToolsPluginRegistration folder of the SDK download.
  2. Run the Plug-in Registration tool.
  3. Connect to a Microsoft Dynamics CRM server and organization. For more information on connecting to a server and organization, refer to the SDK topic: Walkthrough: Register a Plug-in Using the Plug-in Registration Tool.
  4. Register a plug-in and step on the Microsoft Dynamics CRM server. Keep a copy of the debug compiled plug-in assembly on the computer where you are running the tool.
  5. In the tool’s main window, select Install Profiler. You will now see a Plug-in Profiler node in the list.
  6. Select a plug-in step and click Profile to enable profiling.
  7. Perform the operation in Microsoft Dynamics CRM that causes the plug-in to run. For example, if the step is configured for an update to an account, then update an account.
  8. After the plug-in throws an exception and the Business Process Error dialog is displayed, click Download Log File and save this file. Alternately, if the plug-in does not throw an exception, click Stop Profiling.
  9. In the Plug-in Registration tool, click Debug.
  10. In the Debug Existing Plug-in dialog box, provide the location of the previously saved log file.
  11. In Step #2, specify the location of the plug-in assembly.
  12. Launch Visual Studio 2010 and attach the debugger to the PluginRegistration.exe process.
  13. Set a breakpoint in the plug-in code.
  14. Click Start Plug-in Execution in the Debug Existing Plug-in dialog box.
  15. After a slight delay, the plug-in will execute using the same execution context that was passed to it by the Microsoft Dynamics CRM server and the debugger will stop execution on the breakpoint that you previously set.
  16. Continue debugging the plug-in as you would normally do. Any traces that the plug-in outputs are shown in the Debug Existing Plug-in dialog box.

At this point you can alter the plug-in code, build it, re-attach the debugger to the PluginRegistration.exe process, and click Start Plug-in Execution to continue with your debugging session. While performing these operations, you do not need to close the Debug Existing Plug-in form.

You do not need to re-deploy the plug-in to the Microsoft Dynamics CRM server until after you have fixed the code problem. This debugging scenario works even if you have an optimized version of the plug-in on the server and a debug version of the plug-in on the computer where you are debugging.

2. Replay Plug-in Execution

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.

To replay plug-in execution

  1. Launch Visual Studio 2010 and attach the debugger to the PluginRegistration.exe process.
  2. Click Replay Plug-in Execution in the Debug Existing Plug-in dialog box.
  3. Enter the log and plug-in assembly locations in the dialog box.
  4. Click Start Plug-in Execution.
  5. Debug the plug-in as you would normally.

 

3. Run the Plug-in Profiler Standalone

The profiler can be executed from a Prompt window independent of the Plug-in Registration tool. This is useful to obtain the plug-in profile log from a customer’s Microsoft Dynamics CRM server to debug a failed plug-in. A developer can then use that log to replay the plug-in’s execution in the Plug-in Registration tool and debug the plug-in using Visual Studio 2010.

To run the plug-in profiler from a command prompt

  1. Open a Command Prompt window and set the working directory to the Bin folder in the SDK download.
  2. Type the command: PluginProfiler.Debugger.exe /?.
  3. Review the supported parameter list and re-run the PluginProfiler.Debugger.exe program with the appropriate parameters.

Microsoft Dynamics CRM Server 2011 installed configuration components

From this page.

When you install Microsoft Dynamics CRM Server 2011, Setup creates the default folders listed in the following table.

Folder

Comments

SystemDrive:Program FilesMicrosoft Dynamics CRM

Microsoft Dynamics CRM Server 2011 program files

SystemDrive:Program FilesMicrosoft Dynamics CRMLangPacks<LanguageID>ReportsMSCRM

Contains a Microsoft Dynamics CRM subfolder that contains an .rdl file for each default report

SystemDrive:Program FilesMicrosoft Dynamics CRMLangPacks

Location of Language Pack installations. Language Packs are downloaded and installed separately

SystemDrive:Program FilesMicrosoft Dynamics CRMTrace

Stores trace file logs when tracing is enabled

SystemDrive:Program FilesMicrosoft Dynamics CRMCRMWeb

Microsoft Dynamics CRM Web site and Web services

SystemDrive:Program FilesMicrosoft Dynamics CRMCRMWebCRMReports

Microsoft Dynamics CRM report services

The following Web components are added.

Component

Name

Description

Application Pool

CRMAppPool

Microsoft Dynamics CRM Server Setup creates a separate application pool for the Microsoft Dynamics CRM application.

Application Pool

CRMDeploymentServiceAppPool

Microsoft Dynamics CRM Server Setup creates a separate application pool for the Deployment Web Service.

Site

Microsoft Dynamics CRM

Web site for Microsoft Dynamics CRM.

Applications

XRMDeployment

Facilitates the implementation of xRM deployments.

Applications

Help

Services the Microsoft Dynamics CRM Help system for the application.

The following Active Directory groups are added. When the Active Directory domain is set to Native Mode, this group must be of the type Domain Local Security or Universal Security.

Group

Description

PrivReportingGroup

Privileged Microsoft Dynamics CRM user group for reporting functions. This group is created during Microsoft Dynamics CRM Server Setup and configured during Microsoft Dynamics CRM Reporting Extensions Setup.

PrivUserGroup

Privileged Microsoft Dynamics CRM user group for special administrative functions; including CRMAppPool identity (domain user or NetworkService). The users who configure Microsoft Dynamics CRM Server 2011 must be added to this group.

SQLAccessGroup

All server processes/service accounts that require access to SQL Server; including CRMAppPool identity (domain user or NetworkService). Members of this group have db_owner permission on the Microsoft Dynamics CRM databases.

ReportingGroup

All Microsoft Dynamics CRM users are included in this group. This group is updated automatically as users are added and removed from Microsoft Dynamics CRM. By default, all Microsoft Dynamics CRM Reporting Services reports grant Browse permission to this group.

The following services are added.

Service

Description

Microsoft Dynamics CRM Asynchronous Processing Service

Services asynchronous processes such as bulk e-mail and workflow.

Microsoft Dynamics CRM Asynchronous Processing Service (maintenance)

Services asynchronous maintenance such as encryption key generation for authentication and database deletion clean up.

Microsoft Dynamics CRM Unzip Service

Handles the uncompressing of zipped files for data import. This service is installed as part of the Web Application Server role.

Microsoft Dynamics CRM Sandbox Processing Service

The Sandbox Processing Service server role enables an isolated environment to allow for the execution of custom code, such as plug-ins.

The following SQL Server components are added.

Component

Name

Description

Databases

MSCRM_CONFIG

OrganizationName_MSCRM

Microsoft SQL Server Setup creates the SystemDrive:Program FilesMicrosoft SQL ServerMSSQL<ver>MSSQLData folder and Microsoft Dynamics CRM Server Setup installs the Microsoft Dynamics CRM configuration database and organization databases in it.

SQL Server Jobs

OrganizationName_MSCRM.CreateAuditPartition

MSCRM_CONFIG.HardDelete

MSCRM_CONFIG.SiteWideCleanup

Microsoft Dynamics CRM Server Setup creates three SQL Server jobs that are used for maintenance.

Logins

PrivReportingGroup

ReportingGroup

SQLAccessGroup

Microsoft Dynamics CRM Server Setup creates several SQL Server logins for the Active Directory groups that are created.

CRM 2011 – The entity with a name “new_entity” was not found in the metadatacache

Today I encountered a strange issue while working with CRM 2011. So, I have made a Web Resource containing an html file. Basically, what the html file does is call a URL to display the “Create” version of the entity’s form. And that web resource is embedded in a dashboard.

So the html file contains one line of JavaScript as follows:

window.location.href = “/main.aspx?etn=new_entity&extraqs=%3fetn%3dnew_entity&pagetype=entityrecord“;

So, part of the dashboard actually displays the create form of an entity. Fair enough. This worked fine during development, but after importing the solution on another on-premise crm instance, instead of seeing my form, I received the error “The entity with a name “new_entity” was not found in the metadatacache”.

Strange. I searched the web a little, did an iisreset, nothing. After starting the CRM server trace though, I could see that the error was correctly logged, but realized that the organization guid mentioned for the error was another organization’s guid installed on the same server!

So I thought Internet Explorer was messing things up a little with this one. Then I ran a test, setting the absolute URL actually made the thing work! Ok, but then my solution becomes dependent on this organization…

So I finally realized it was not IE but me forgetting I had designed this solution on an online CRM instance. And I forgot that I had to include the name of the organization in the URL. So I came up with this JavaScript snippet to quickly get the org name:

var a = window.location.href; // Just for readibility
var sub1 = a.substring(a.indexOf(‘//’) + 2);
var sub2 = sub1.substring(sub1.indexOf(‘/’) + 1);
var org = sub2.substring(0, sub2.indexOf(‘/’));

This gives the name of the organization present in the URL, without any slash. Included in my original script:

window.location.href = “/” + org + “/main.aspx?etn=new_entity&extraqs=%3fetn%3dnew_entity&pagetype=entityrecord“;

That was it! Probably not my most glorious coding moment, but still worth sharing I think.

 

CRM 2011 – How to refresh a view in the Outlook Client

Strange thing but in the CRM Outlook Client, Microsoft did not reproduce the small green arrows that are visible in the Web Client.

Here’s what you have in the Web Client to refresh a view:

 

CRM 2011 - Web Client - Refresh View
CRM 2011 - Web Client - Refresh View

 

And here’s what you get in the Outlook client: no refresh button! The green arrows are gone.

 

CRM 2011 - Outlook Client - No Refresh View
CRM 2011 - Outlook Client - No Refresh View

 

So here’s the trick: to refresh the view, click on the “View” menu in th ribbon, and there is the Refresh button!

 

CRM 2011 - Outlook Client - Refresh View
CRM 2011 - Outlook Client - Refresh View