Retrieving the Current User in Dynamics CRM 4 ISV ASP.Net

September 20, 2011

If you are manipulating user-related data in a Dynamics CRM ASP.Net application (i.e. under the ISV sub-directory), you need to retrieve the currently logged-on user, for example to set the ownerid value for a newly created record belonging to the current user..

Initial research led me to the WhoAmIRequest class which I excepted to return the current systemuser (as many others).

However, what the request really returns is the systemuser associated with the Dynamics login credentials, as the vaguely formulated introduction on MSDN suggests:

Contains the data needed toretrieve the system user ID for the currently logged on user or the user under whose context the code is running

To retrieve the current user, the CRM-related HttpModules are required in the web.config:

<httpModules>
  <add name ="MapOrg"
    type="Microsoft.Crm.MapOrgEngine, Microsoft.Crm,
      Version=4.0.0.0, Culture=neutral,
      PublicKeyToken=31bf3856ad364e35"/>
  <add name ="CrmAuthentication"
    type="Microsoft.Crm.Authentication.AuthenticationEngine,
      Microsoft.Crm, Version=4.0.0.0, Culture=neutral,
      PublicKeyToken=31bf3856ad364e35"/>
</httpModules>

These modules are typically included in the CRM’s web.config, so there should be no need to include them in ISV as well. You must not remove them using the <remove name=”CrmAuthentication” /> tag!

You can then go ahead and create a CrmAuthenticationToken from the web request using the static method CrmAuthenticationToken.ExtractCrmAuthenticationToken():

Guid GetCallingUserId()
{
  if (Request.IsLocal)
  {
    return new Microsoft.Crm.Sdk.CrmAuthenticationToken()
      .CallerId;
  }
  else
  {
    string orgname = Request["orgname"];
    return Microsoft.Crm.Sdk.CrmAuthenticationToken
      .ExtractCrmAuthenticationToken(Context, orgname)
      .CallerId;
  }
}

How do you pass the organization name to the .aspx?

In the ISV.config, set the MenuItem‘s PassParams attribute to “1″ if the menu item defines a Url property.

If the menu item defines a JavaScript attribute to execute JavaScript upon selection, include the ORG_UNIQUE_NAME variable in the JS code:

<MenuItem JavaScript="window.open(
  '../../../ISV/path/to/mypage.aspx?orgname='
  + ORG_UNIQUE_NAME + '&amp;other-params');">

(thanks to SO for this hint)


Type-safe Queries in Dynamics CRM 4

September 20, 2011

Avoiding string literals and writing type-safe code as supported by the compiler are among my favorite code-writing philosophies.

So when I started to work on a Dynamics CRM project, which by default uses strings for table and column names (fortunately, table names can be accessed by the EntityNames enumeration), I wished there was a Linq-like way to access the CRM Service.

Therefore, the first code I wrote was a method implementing a type-safe query encapsulating RetrieveMultiple():

public static List<T> RetrieveMultiple<T>(this CrmService service)
  where T : BusinessEntity
{
  List<T> result = new List<T>();

  QueryExpression query = new QueryExpression();
  query.EntityName = typeof(T).Name;      
  query.ColumnSet = new AllColumns();

  BusinessEntityCollection retrieved = service.RetrieveMultiple(query);
  foreach (T item in retrieved.BusinessEntities)
    result.Add(item);

  return result;
}

While not very powerful and flexible, this method provides both type-safe compilablity and avoidance of string literals.

After some research, I found that there are already libraries supporting Linq queries for Dynamics CRM:

These libraries come with an overhead though:

  • LINQtoCRM requires all queries to be created through its CrmQueryProvider class.
  • xRM provides Linq queries through its XrmDataContext class which requires a connection string in the .config file and generating DTOs using CrmSvcUtil.

Both options may be challenging to include in an already existing project.


Extracting .msi Files without Installation

September 19, 2011

Occasionally you need to access the contents of an .msi file, but you are sitting on a PC where you do not administrative rights to run the installer.

I noticed 7-Zip adds itself to the context menu of .msi files, but it extracts the whole contents of the msi, and the output is somewhat confusing to me (admittedly, I do not use the latest version of 7-Zip).

Fortunately I came across lessmsi which opens an .msi file, allows you to select the desired files, and extracts them into the file’s sub-directory as found in the Directory column of each of the contained files.

Simple and effective!


Fourth Anniversary

September 14, 2011

12 month summary:

  • Started the Series category to collect posts on the same topic

The raw sums: 282,000 views, 375 posts, 6,500 downloads.


Series: Virtual Static Interface Methods in C#

September 2, 2011

A topic that was on my imaginary “C# Wishlist” until I found out

1) why it’s a bad idea and

2) how to implement it with techniques C# already provides.

So the series should really be called “Virtual Static Interface Methods in C# – and why you do not need them” ;)

Introduction

Virtual Static Interface Methods in C# – Introduction

First Implementation

Virtual Static Interface Methods in C# – Implementation

Updated Implementation

Even “More Static” Virtual Static Interface Methods in C#


Database Dependency Diagrams

September 1, 2011

Preparing the release of the next version of dbscript, I can proudly present you one of its new functions: to generate a Dependency Diagram of all objects contained in a database:


dependency diagram of AdventureWorks 2008 (png)

dependency diagram of AdventureWorks 2008 (dia screenshot)As usual, the diagrams can be generated in .png and .dia format.

Dependency analysis and dependency diagram generation are currently only implemented for MS SQL Server databases.


Follow

Get every new post delivered to your Inbox.