Tag Archives: CRM

Design for Online

UPDATE (30MAY2013): Have a look at this post for some tangible examples of Windows Azure with CRM to address some of these scenarios.

DISCLAIMER: This post is not official guidance from Microsoft.  It’s the thoughts and opinion of one guy who has been spending a fair amount of time talking to customers and partners about what I’ve been calling the “Design for Online” principles.  These are just my “brain dump” notes of what I’ve learned along the way.  Therefore, feel free to leave comments and provide feedback to make this post better.

In many ways, this post is a different spin on my CRM Online myth busters post.  However, instead of forcing you to reverse engineer “Design for Online” principles from a bunch of busted myths, I decided to lay out what I believe to be the key design decisions and pointers you need to make sure you have a solution that will run relatively unchanged in any deployment environment: CRM 2011 installed in your datacenter (OnPrem), CRM Online, or another hosting provider.  I think that everyone should be forcing themselves to embody these principles in ANY solution they build on top of CRM 2011.  Why?  It gives you deployment flexibility.  I’ve worked with a few folks who wanted to move to CRM Online and were disappointed that their solution wasn’t built in such a way that could get them there without major rework.  If they had built with “Design for Online” in mind, then they would be much happier right now.  Also, I just think that on-prem apps shouldn’t be designed with “legacy design principles.”  They should be designed with modern design principles including separation of concerns and the isolation you get when you stick to these principles.  At a high level, the principles can be summed up as:

  • Use Claims-based authentication
  • Run everything under SSL
  • Deploy all .NET assemblies (plugins / workflow activities) to the sandbox / database
  • Use ILMerge with third party assemblies
  • Put full trust code somewhere else
  • Configure any UI mash up integration for Single Sign-on
  • Pretend the Filtered Views don’t exist
  • Build all of your Reporting Services reports using FetchXML

 

Use Claims-based authentication

As I mentioned in my CRM Online myth busters post, CRM Online supports ADFS 2.0.  Claims-based authentication doesn’t mean you have to have an Internet Facing Deployment (IFD).  However, if you want to go IFD, you have to use Claims-based authentication anyway.  If you have the option, you should always go with this as your authentication choice.  This is also a key to enabler to Single Sign-On (SSO) with other pieces of your application (ASP.NET pages, SharePoint, etc.) whether you are on your corporate network or accessing CRM from any internet connection.  A good place to start is Configuring Claims-based Authentication for Microsoft Dynamics CRM 2011.  Also, the Microsoft Dynamics CRM 2011 Implementation Guide has a specific whitepaper called Microsoft Dynamics CRM 2011 and Claims-based Authentication.doc you should have a look at as well.

 

Run everything under SSL

This is actually a requirement for Claims-based authentication, but I felt it was worth calling out by itself.

 

Deploy all .NET assemblies (plugins / workflow activities) to the sandbox / database

This is the first place I hear a fair amount of developer / solution architect angst.  Lots of “Yea, but what if…” retorts.  I’ll get to those.  Keep reading.  If you aren’t familiar with the sandbox, then make sure you read Plug-in Isolation, Trusts, and Statistics.  Do not change the registry key mentioned at the end of the article.  If you are Using the Plug-in Registration Tool for Microsoft Dynamics CRM 2011, then make sure you set Step #3: Specify the Isolation Mode to Sandbox and Step #4: Specify the Location where the Assembly should be stored to Database when Registering a Plug-in or Custom Workflow Activity.  If you are using the Developer Toolkit for Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online, then it defaults to this form of registration.

 

Use ILMerge with third party assemblies

Code within sandbox deployed assemblies is constrained to using .NET Framework assemblies, the public assemblies that are part of the Microsoft Dynamics CRM 2011 Software Development Kit (SDK), and the code inside the assembly itself.  If you need to leverage a third party assembly, then consider using ILMerge.  There are two blog posts I find useful to get this configured here and here.  The second post is a little old and talks about .NET 3.5.  Ignore that part.  The useful part of the second post is how to configure Visual Studio to use ILMerge as a post build activity.

 

Put full trust code somewhere else

Sometimes, you just have to write code that won’t run in the sandbox.  Resist the urge to violate the Deploy all .NET assemblies (plugins / workflow activities) to the sandbox / database principle.  Instead, put the code requiring elevated trust behind a web service hosted in a separate process that you own.  Call it from the plugin / workflow assembly.    In the OnPrem world, the web service will probably be running on Windows Server in its own web site.  In CRM Online, the web service will probably be running in a Windows Azure Web Role.  Also, OnPrem this can run on the same physical server as the CRM 2011 front-end servers even though you are going to have to run the site on a separate subdomain.  See Binding multiple domains to a wildcard SSL on a single IP in IIS 7.5 for more details.  There are some key implementation details for this to work:

  • Use the trusted subsystem pattern to authenticate from the plugin code to the external web service using a single identity.
  • If the code running behind your web service needs to call back into Dynamics CRM, then:
    • The web service code in turn uses the trusted subsystem pattern to authenticate back to CRM via the Organization Service using a single identity.  This is typically a CRM user you’ve created specifically for trusted subsystem use.  There are a number of samples for connecting to the Organization Service from .NET code, but the Simplified Connection to Microsoft Dynamics CRM really does make it simple!
    • If you need the CRM Organization Service to execute under the context of the original user the plugin code ran under, then you will need to Impersonate Another User.  Therefore, you will need to pass CallerId from the plugin code to your web service code, which will then passes it back to the CRM Organization Service.

This all seems a little daunting when you first hear/read it, but after you’ve done it once you will realize it isn’t as daunting as it sounds.  Consider this scenario the exception, not the rule.  A few other little tidbits of information to help you implement this scenario:

    • Consider making your web service a REST service.  There is generally less overhead and a smaller data payload across the wire especially if you use JSON serialization.  There really isn’t anything about these services that require SOAP, unless you just prefer the SOAP service programming model better.
    • If you prefer to use a SOAP service, then have a look at:
<customBinding>

  <binding name="NetHttpBinding">

     <binaryMessageEncoding />

     <httpsTransport />

  </binding>

</customBinding>

      • If you use binary encoding, then modify the code in the Calling WCF Service in Plugin in CRM link to reflect it:
BindingElementCollection elements = new BindingElementCollection();

elements.Add(new BinaryMessageEncodingBindingElement());

 

elements.Add(new HttpsTransportBindingElement());

 

CustomBinding binding = new CustomBinding(elements);

 

Configure any UI mash up integration for Single Sign-on

While less prevalent with the advent of web resources in CRM 2011, there are still times where you want to write custom ASP.NET code or even REST services that you want to integrate (or mash up) into the CRM UI, but need to write server side code for them.  The only supported way to do that in CRM 2011 is to have a companion site and Implement Single Sign-on from an ASPX Webpage or IFRAME.  In the OnPrem world, the content will probably be running on Windows Server in its own web site.  In CRM Online, the content will probably be running in a Windows Azure Web Role.  By doing taking this approach, you can no longer use window.parent for cross frame communication because you will be in a cross domain scenario. See Cross domain calls to the parent CRM 2011 form.  Another scenario that you may not realize is a UI mash up integration is the out of the box SharePoint integration for CRM 2011.  More details here.  However, if you’ve configured single sign-on across these three sites (CRM/SharePoint/Companion Site), then it all just works at the UI layer.  This is why principle #1 is Use Claims-based authentication.

 

Pretend the Filtered Views don’t exist

Plain and simple, CRM Online doesn’t support direct access to the database.  Therefore, in the world of CRM Online, the Filtered Views don’t exist.  Write all of our code against the CRM web services.

 

Build all of your Reporting Services reports using FetchXML

In order to build FetchXML SSRS reports, you need to install the Microsoft Dynamics CRM 2011 Report Authoring Extension on the same PC in which you have Business Intelligence Development Studio (BIDS) installed.  This adds a Fetch XML data source.  From there, you just follow the directions in Create Custom Reports Using Business Intelligence Development Studio.  SSRS reports in CRM Online are Sandboxed.  See RDL Sandboxing for Microsoft Dynamics CRM Online for more details.  One of the objections I often hear is “but I really want to write my queries in SQL because that’s what I know.”  I “get it.”  For now, FetchXML it is.  For most, I recommend using the Advanced Find feature of the CRM UI to compose the query, then click the Download Fetch XML button. 

image

For advanced query capabilities of FetchXML that aren’t possible through Advanced Find, you will need to start with Advanced Find, then modify the XML yourself.  See Build Queries with FetchXML for more details.  Personally, I’m not “GUI Query Tool” guy.  I like to write my queries by hand.  Let’s face it, no one wants to learn “yet another query language” which is what you have to do with FetchXML.  I shield myself from this by using LINQ.  I use LINQPad + LINQPad Plugin for Microsoft Dynamics CRM 2011.  The one gotcha is that the plugin doesn’t produce FetchXML.  There’s a feature request here to enhance the plugin to do so.  VOTE it up!  However, through extensibility of LINQPad, I created an extension method to do the conversion.  See Getting FetchXML from LINQPad for more details.

 

What about integrating with systems behind my firewall from CRM Online?

This isn’t exactly a “Design for Online” principle as much as an answer to the “How do I do it in CRM Online?” question. While CRM Online doesn’t provide any specific capability to securely cross the internet and talk to systems behind an organizational firewall, you can still do it.  CRM Online is from Microsoft.  Microsoft is a platform company that happens to have a platform that already enables such scenarios.  It’s called Windows Azure.  I address this scenario and others in my CRM Online + Windows Azure = Many Possibilities post.  While these approaches enable “from CRM Online” scenarios, meaning code running inside CRM Online calling out, it’s equally important to understand that some integration needs can be met with data integration that can be achieved through tools such as  CozyRoc and Scribe.  Of course, your scenarios will dictate what integration approach is most appropriate.  Also, building optimized data migration code becomes more important when you are calling across the internet moving data from a legacy system to a cloud environment.  I have a post about called Data Migration with CRM 2011 that covers this topic.

 

Summary

Ok, so now I finally have a blog post to point people to that comprehensively covers what I think of as the “Design for Online” principles.  The last point, Yes, I have tried all of this stuff out.  However, I have tried each out in isolation.  I’m planning on putting together a fairly simple reference sample that brings all of this together and demonstrates it running in CRM OnPrem + Windows Server as well as CRM Online + Windows Azure.

@devkeydet

CRM Online myth busters presentation

I’ve created a presentation version of my CRM Online myth busters post.  The goal of the deck is the same as the post, which is to share common misconceptions I run into about CRM Online when speaking with folks.  The presentation is geared towards those who aren’t interested in the technical details from the post.

Direct link: http://dkdt.me/JNFJEm

@devkeydet

Deleting things from a deployed CRM 2011 managed solution package

DISCLAIMER:  This is technically unsupported, but works.  If that makes you cringe, then walk away.  If you read it and think it will work for you, then make the decision that’s best for you.

Example scenarios:

“I have a a field in an entity.  After deploying a managed solution to production, we decided we don’t need that field any longer.  I removed it from my development environment.  When I deploy an updated version of managed solution in production, the old field is still there.  I know it’s harmless to keep it in production, but I want it gone.”

“I renamed a web resource in development after already deploying it to production in a managed solution.  None of my code references it any longer.  When I deploy an updated version of the managed solution, the old web resource is still there.  I want it gone.”

This was something that stumped me when I started focusing on Dynamics CRM 2011.  Technically, the CRM solution package infrastructure has no way to delete something.  However, Shan McArthur explained to me that there is a way to accomplish deletes.  I plan on using this approach in the next release of my validation sample because I did some significant refactoring since my first release.  The general concept is to:

  • Create a temporary managed solution to “hold” the latest “good bits” using the same publisher
  • Import it on top of your existing managed solution
  • Delete the older managed solution
    • This deletes the older stuff while the “holding” solution prevents the “good bits” from being removed
  • Import the new version of the managed solution
  • Delete “holding” managed solution

Let’s walk through this step by step.  You can download the three files to try this yourself here.  I have two orgs: dev and target.  In my dev org, everything is unmanaged:

image

In my target org, I have already deployed the 1.0 managed solution that was exported from my dev org:

image

If you want to try this out yourself, just import the 1.0 managed solution into your own CRM 2011 org.  Here’s a look at the form in it’s current state:

image

Notice that it has a “delete me” field and web resource.  For version 1.1, in my dev environment,  I went ahead and removed the two items from the form, then deleted the field from the entity:

image

…and and the web resource from the solution:

image

Next, I updated the version to 1.1:

image

Finally, I exported the 1.1 version as a managed solution (make sure all your customizations are published).  Ok, so we have the old and new managed solution version.  How do we create the “holding” solution?  Unzip the 1.1 solution, edit the contents of solution.xml like so:

image

I use _HOLDING in UniqueName and LocalizedName to make it obvious.  After you have saved the changes to the solution.xml file, zip up the contents of the unzipped folder:

image

…and name it something unique.  My conventions is to use a name similar to the latest managed solution it will “hold” for:

image

I replace _managed with _HOLDING in the name of the file.  Ok, now you are ready to accomplish a delete.  If you are still following along using the sample files, then do the following:

  • Import devkeydetDeleteExample_1_0_managed.zip if you haven’t already
  • Import devkeydetDeleteExample_1_1_HOLDING.zip
  • Delete devkeydetDeleteExample_1_0_managed.zip (deletes what’s not in the holding solution)
  • Import devkeydetDeleteExample_1_1_managed.zip (creates the proper UniqueName reference to the items in the holding solution)
  • Delete devkeydetDeleteExample_1_0_HOLDING.zip (removes nothing but the solution based on the temporary UniqueName)

The end result is that you will have the items you deleted in your dev environment deleted in your target environment and the solution UniqueName is maintained.  Thanks again to Shan McArthur for explaining this to me.  This general approach can be applied to other “delete stuff that’s no longer used” scenarios as well.

@devkeydet

Using RequireJS with CRM 2011 forms

GOAL: Simplify referencing JavaScript libraries from CRM forms for code-centric developer types like me.

I have always been a fan of “code beside” JavaScript files that contain all my main code for a corresponding HTML page.  For example, if I have a page called hello.htm, then I will have a file called hello.htm.js that is the main code file for that page.  One of the things I have always been a bit frustrated with when using this approach is that all the JavaScript libraries my hello.htm.js page uses are actually referenced in the HTML page.  This leads to a lot of switching back and forth between the files when you need to add script references.  It also becomes a burden when you are reviewing code you haven’t worked with in a while.  You inevitably have to switch to the hello.htm page to familiarize yourself with what other js files the page references.  My brain has challenges with this context switch.  Coming from a .NET development background, I am used to namespaces at the top of my C# files that help me with this.  I’ve recently gotten hip to RequireJS which is a library that makes it really easy to add JavaScript references to a page right from JavaScript.  While you can technically do this without RequireJS, the library wraps the verbose code and all the cross browser nuances plus adds some nice features.  Check it out!

Ok, now to the CRM 2011 context…

I’ve always found it a bit cumbersome to have to “point and click” my way to adding JavaScript references to a CRM 2011 form.  I totally get that this is useful for building reusable JavaScript libraries that non-devs can use / configure by passing parameters.  However, my mode of operation is usually to have a single JavaScript web resource for the form that programmatically wires up events, etc.  Sound familiar?  I usually think of it as my “code beside” or “View Model” for the form.  Since I often have reusable libraries I want to reference from my primary JavaScript web resource, it would be nice not to have to “point and click” my way to adding them.  Thereby having a single JavaScript file that I can read top to bottom to understand everything that’s going on in the form.  Here’s how I do it…

Deploy RequireJS as a web resource and add it to your form, then add another web resource to the form that contains your “View Model” for the form:

image

In my case the “View Model” resource is called dkdt_/scripts/requirejsttest.js.  Make sure you’ve wired up the form to call the starting function in your web resource.  In my case the function is called dkdt_OnLoad.  Here’s the code for the requirejstest.js web resource:

function dkdt_OnLoad() {

    var serverUrl = Xrm.Page.context.getServerUrl();

    var requiredScript = serverUrl + "/WebResources/dkdt_/scripts/somerequiredscript.js";

 

    require([requiredScript], function (m) {      

        dkdt_ConfirmThisLoaded();

    });

}

The source code for the somerequiredscript.js web resource looks like:

function dkdt_ConfirmThisLoaded() {

    alert("The required script loaded");

}

This may seem straightforward, but figuring out what to pass to the require() function took a little investigation.  When using IE10s “F12 Developer Tools,” I noticed that the JavaScript web resources loaded into the form are children of a page called edit.aspx which lives under [serverUrl]/userdefined:

image

The only consistent way I could figure out to tell RequireJS to load the right web resource was to build the full url programmatically.  If you know of a better way, let me know in the comments. 

The way I use this approach is that all of my forms always have a “point and click” reference to require.js and the main JavaScript web resource for the form (requirejsttest.js in this example).  I tend to make the initial function the same for every form as a convention (dkdt_OnLoad in this example).  Everything else, including event wire up and additional JavaScript file references are done in the main web resource of the form.  This gives me a single file to read and understand what’s going on in the form, including what additional JavaScript web resources the code depends on without having to “point and click” my way to finding out.

@devkeydet

Data Migration with CRM 2011

UPDATE (18APR2013): If you find this post interesting, then you will want to watch the Enterprise Data Integration for CRM, featuring Daniel Cai webcast.

“I am building a solution using CRM 2011, but I need to migrate a significant amount of data from an existing system.  The Import Data wizard in the CRM 211 UI doesn’t meet my needs due to the amount of data and the logic necessary to transform the data from the source system into the destination system.”

This scenario is often referred to as Extract Transform and Load (ETL).  The first thing most people look at is using SQL Server Integrations Services (SSIS), because it is the ETL tool that comes with SQL Server.  The only supported way to perform Create Update and Delete operations against CRM 2011 is to go through the CRM Web Services.  While it is possible to call a web service from SSIS out of the box, the reality is that the level of effort is arguably higher than most expect when interacting with the CRM 2011 Web Services.  Because of this, there are two companies (that I am aware of) who provide add-ons to SSIS:

http://cozyroc.com/

http://www.kingswaysoft.com/products/ssis-integration-toolkit-for-microsoft-dynamics-crm 

These add-ons greatly improve productivity when performing CRUD operations through the CRM Web Services.  I’ve personally never used either, but I’ve spoken with folks who have.  Those people claim that these add-ins are well worth the license fee compared to creating the SSIS packages without one.  Once people have built SSIS packages to perform data migration, they inevitably want to know how they can improve the performance of the data import.  One of the first things you should consider is executing parts of your package in parallel where possible.  There’s another add-on for SSIS called the Balanced Data Distributor that helps you parallelize: 

http://blogs.msdn.com/b/sqlperf/archive/2011/05/25/the-balanced-data-distributor-for-ssis.aspx

This one is free.  Make sure you check out link to the video in the comments of the post.  Of course performance will improve if you run this on hardware that has more CPUs/Cores.  There are also some other things to take into consideration when it comes to performance of data imports for CRM 2011. 

  • First, you want to make sure you’ve optimized your CRM server infrastructure (see here).  Following the optimization guidelines makes a difference.
  • Where possible, deactivate workflows and plugin messages before importing large amounts of data.  Reactivate after import is complete.
  • It’s also possible to improve performance by dropping indexes and rebuilding them after the import is complete.  However, index rebuild time needs to be considered.
  • Disable statistics, then re-enable after import is completed (see here)

Whether you can apply some of these depends on your data import scenarios.  For example, if you have to import data during normal usage hours, some of these may not be feasible.  But then again, you probably shouldn’t be “migrating a significant amount of data” during normal usage hours.

You may be asking yourself: “What about Scribe?”  Scribe makes wonderful tools that do much more than what’s needed for basic ETL scenarios.  The focus of this post the scenarios for which ETL with SSIS makes the most sense.

UPDATE: Last, but definitely not least as a few folks have pointed out, it’s important to understand the fundamentals of a well built / optimized SSIS package.  This post was intended to cover with the CRM nuances.  Here are a few links to help with the fundamentals:

Top 10 SQL Server Integration Services Best Practices

SQL Server Integration Services SSIS Best Practices

 

@devkeydet

CRM 2011 OnPrem integrating with SharePoint Online

“Can I get the the integration the Microsoft Dynamics CRM 2011 List Component for Microsoft SharePoint Server 2010 provides to work with SharePoint Online when my CRM 2011 deployment is OnPrem (i.e. installed inside my organizations private network or somewhere else that’s not CRM Online)?”

The answer is Yes with a few caveats / configuration hints. 

First, you have to understand that the built in integration between CRM 2011 and SharePoint 2010, enabled through the List Component, is actually at the UI level. 

image

Everything inside this highlighted blue border is UI rendered on the SharePoint server and surfaced through an iFrame.  The CRM 2011 List Component for Microsoft SharePoint 2010 is responsible for the CRM 2011 look and feel.  CRM 2011 just stores metadata about SharePoint in a set of Entities.  Therefore, you will obviously need internet connectivity from your browser.

But remember, the scenario we want to get working is a “hybrid solution” where SharePoint Online is “in the cloud” and CRM 2011 is OnPrem.  If you just follow the instructions provided through the Configuring the List Component in SharePoint Online blog post, there is a good chance will run into issues with these instructions. 

The first caveat for this scenario is that you have to take authentication into consideration.  If you are one of the more advanced organizations using Office 365 configured to work with your Active Directory Federation Services (ADFS) 2.0 deployment for authentication, then you likely have Single Sign On (SSO) working.  In that case, the Configuring the List Component in SharePoint Online instructions should “just work.”  However, if you aren’t, then you will have to make sure you are logged in to SharePoint Online first.  Once you’ve done that, you can follow the Configuring the List Component in SharePoint Online instructions.  That is IF your CRM 2011 deployment is configured for https.  If not you will run into browser warnings about “mixed mode” and subsequent issues due to your CRM 2011 deployment running under http and your SharePoint Online deployment running under https.  This is to be expected.  To remove the warnings and resolve the issues, make sure you’ve added your SharePoint Online site and your CRM 2011 site to the IE “Trusted sites” list. 

image

In my case, that’s “http://crm2011” and “*.sharepoint.com” in the screenshot.  However, you could choose to be more granular and enter “yoursubdomain.sharepoint.com” for SharePoint Online if you like.  Finally, make sure that you configure a “custom level” setting for your trusted sites to enable the display of mixed content without prompts:

image

If you weren’t in a position to follow the Configuring the List Component in SharePoint Online instructions before, then you should be now.  Again, both initial configuration AND end user scenarios will require the user to login to SharePoint Online first before you bring up your CRM UI, unless you have SSO configured.

@devkeydet

CRMUG: Transforming Policy to Economic Growth with Microsoft Dynamics CRM

NOTE: This is a copy/paste/minor tweak of an email invite I got from someone on my team.

REGISTER TODAY: http://dkdt.me/K0bBK6

The Microsoft Dynamics® CRM User Group (CRMUG) has monthly open forum discussions of Dynamics CRM issues facing Public Sector organizations today.

The next web meeting will take place Thursday, May 3rd 2012 at 1pm EST so don’t miss this opportunity!  This month’s topic is geared towards government business decision makers who are interested in discussing ways to solve some of the most pressing public policy issues with CRM.
In this meeting, the topic of discussion will be “Transforming Policy to Economic Growth with Microsoft Dynamics CRM”.  Our guest speaker and moderator will be Herbert Quinde, State of Illinois Chief of IT Policy and Planning.

Microsoft Dynamics CRM is increasingly becoming a strategic asset for public sector.  This sessions allows attendees to discuss how solutions, like CRM, are critical in the public sector  by transforming how Federal, State & Local governments address changing processes and manage organizational business for future success. The ultimate goal is always to help shape our communities through innovation and time amongst this thought leadership group is part of achieving that goal.

This session is part of a quarterly focus Public Sector Special Interest Group (SIG) to provide business leaders the opportunity to review issues and experiences with Dynamics CRM. Participants are encouraged to share, listen, and learn about experiences in order to build cutting-edge programs and solutions that drive real impact for a better tomorrow in the public sector.

Participation in these webinars is free of charge and open to all Microsoft Dynamics CRM users within Federal, State & Local governments so don’t miss your opportunity to register!         

Event Details

· What: Open Forum Webinar for Federal, State & Local Government Dynamics CRM Users

· Who:  Government IT and agency leadership

· Where: Online

· When: May 3rd, 2012 from 1:00pm-2:00pm EST

· Why: To share and learn about Dynamics CRM experiences in the public sector

@devkeydet 

Effective Use of Solutions in CRM 2011 with Shan McArthur

I have a had a number of people about how to effectively use the Solutions capability of CRM 2011.  It has reminded me of great recorded webcast I found out about through conversation I had in an internal email discussion:

Effective Use of Solutions in CRM 2011 with Shan McArthur

I wanted to do some significant refactoring in a managed solution.  I wanted to delete and/or rename some things in my solution and reconcile those deletions.  Shan McArthur shared a tip on how to delete something from a managed solution.  He mentioned that he talks about this tip the webcast he presented for the XRM Virtual User Group (about 56 minutes in).  I have had an item on my TODO list to blog about it.  One thing checked off of a long list!  This webcast is definitely worth taking the time to watch if you aren’t quite sure if you’ve nailed your understanding of the Solutions capability of CRM 2011.

@devkeydet

Different ‘apps’ in a CRM 2011 organization (tenant)

Scenario:

“We, conceptually, have two ‘apps’ within a single Dynamics CRM organization.  The ‘apps’ share a common set of entities such as Contacts.  We want to control which ‘apps’ show up in the Dynamics CRM navigation Area for a given user based on Security Roles.  The user has rights to entities that show up in both navigation Areas.  How do we enable this scenario?”

The trick is in understanding how security trimming of the Site Map works.  You might want to read this blog post as a backgrounder:

Hiding Areas in the Sitemap

I’ll build on the post above to show how to enable the scenario.  Let’s start with the example:

image

I am logged in as a System Administrator so I have access to both App One and App Two.  Notice the contents of my Solution:

image

The Site Map is a given.  We’ll be modifying it to enable the scenario.  I have two Security Roles:  App One and App Two.  These represent how we differentiate access to different ‘apps’ in the organization.  Finally, you see two entities: privSiteMapAppOne and privSiteMapAppTwo.  These are entities that will never contain data.  They only exist for the purpose of adding a “custom privilege” that can be used from the Site Map.  Here’s a screenshot of each Security Role:

image

image

Notice that each Security Role has Read access to the corresponding “custom privilege entity.”  Now let’s look at the Site Map configuration.  I’m going to be showing it through my favorite Site Map editing tool, but you should be able to do the translation to however you edit the Site Map:

image

Notice that AppGroupOne->BingSubArea has a Privilege child node with Entity set to dkdt_privsitemapappone which is our “custom privilege entity” and the Read checkbox checked.  The way I read this in English is “Only show the BingSubArea navigation link if the user has read access to the dkdt_privsitemapappone entity.”  The XboxSubArea is configured similarly but with the other dkdt_privsitemapapptwo “custom privilege entity”:

image

Ok great, but we still haven’t enabled the scenario.  Why?  Because I’ve also included a SubArea that enables the What’s New navigation link that is part of Activity Feeds.

image

Since both Security Roles have Read access to the post entity, users who are in only one of the two Security Roles will still see both Area navigation links.  Why?  This goes back to understanding how security trimming with Privilege settings work for the Site Map.  If you have rights to see anything within the Area, the navigation link shows up.  You just don’t get to see the children in the area you don’t have access to.  The trick (which is what this whole post has built up to) is to add a second Privilege node to the nav_personalwall SubArea for the corresponding “custom privilege entity.”  Here it is for the AppOneArea node:

image

The way I read this in English is “Only show the nav_personalwall SubArea navigation link if the user has read access to the post entity AND the dkdt_privsitemapappone entity.” 

Do the same for AppTwoArea node:

image

At this point, a user who is in the App One Security Role will only see the App One navigation link:

image

A user who is in the App Two Security Role will only see the App Two navigation link:

image

Users who are assigned to both Security Roles will see both (see the first screenshot in the post).  HTH!

@devkeydet

Getting FetchXML from LINQPad

UPDATE: There’s a known issue with the LINQPad Plugin for Microsoft Dynamics CRM 2011 and Office 365 authentication.  I cover a workaround here.

Using FetchXML is necessary in many situations with CRM 2011.  Using FetchXML becomes even more necessary if you are taking a “design for online” approach to solution building.  I’m a big believer that everyone should approach solution design this way because then your solution will truly be portable between CRM Online and CRM OnPrem (i.e. the CRM you install yourself).  Typically, the need for FetchXML shows up first when you are building custom SQL Server Reporting Services (SSRS) reports.  That’s because FetchXML based reports are the only option in CRM Online.  I mentioned in my CRM Online myth busters post that I prefer to use LINQPad + LINQPad Plugin for Microsoft Dynamics CRM 2011 to compose my queries, then convert them to FetchXML.  This post is a walkthrough of how I do it.  I got the inspiration for the code sample I will present from the following two samples:

http://dkdt.me/JZiDsr

http://dkdt.me/JZiBAO

Once you’ve installed LINQPad + LINQPad Plugin for Microsoft Dynamics CRM 2011, you need to add some code to the “My Extensions” file in the “My Queries” pane:

image

Place the code I provide you below within the MyExtensions class under the comment that says to “write custom extension methods here.”  Here’s what the file looks like before you’ve added anything to it:

void Main()

{

    // Write code to test your extensions here. Press F5 to compile and run.

}

 

public static class MyExtensions

{

    // Write custom extension methods here. They will be available to all queries. 

}

 

// You can also define non-static classes, enums, etc.

Here’s the code you need to add under the comment:

public static string ToFetchXml(this IQueryable linqQuery, dynamic orgService)

{

    var queryExpression = GetQueryExpression(linqQuery);

 

    var expressionToFetchXmlRequest = new Microsoft.Crm.Sdk.Messages.QueryExpressionToFetchXmlRequest

    {

     Query = queryExpression

    };

 

    var organizationResponse = (Microsoft.Crm.Sdk.Messages.QueryExpressionToFetchXmlResponse)orgService.Execute(expressionToFetchXmlRequest);

 

    return organizationResponse.FetchXml;

}

 

private static Microsoft.Xrm.Sdk.Query.QueryExpression GetQueryExpression(IQueryable linqQuery)

{

    object projection = null;

    object source = null;

    object linkLookups = null;

    bool flag = false;

    bool flag2 = false;

 

    object[] arguments = new object[6];

    arguments[0] = (object)linqQuery.Expression;

    arguments[1] = (object)flag;

    arguments[2] = (object)flag2;

    arguments[3] = (object)projection;

    arguments[4] = (object)source;

    arguments[5] = (object)linkLookups;

 

    Microsoft.Xrm.Sdk.Query.QueryExpression query = (Microsoft.Xrm.Sdk.Query.QueryExpression)linqQuery.Provider.GetType().InvokeMember("GetQueryExpression", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, linqQuery.Provider, arguments);

    return query;

}

In addition to adding the code, you need to add references to a few .NET assemblies.  From within the “My Extensions” file, press the F4 key to bring up the properties dialog.  Add references to the following assemblies (note your location for CRM 2011 SDK assemblies might be different):

image

Now, once you’ve written and executed the query that you want in LINQPad:

image

…you can then wrap the query in parenthesis and call the ToFetchXml() extension method to get the FetchXML:

image

BAM!  This approach has really helped me be productive in composing FetchXML queries.  I use this mostly when writing SSRS reports, but also find it useful for other occasions where I need to use FetchXML.  See the LINQ Limitations section of the Use LINQ to Construct a Query documentation for more details.

@devkeydet