SharePoint Integration Reloaded – Part 1

Back in the day when CRM2011 was first in beta I blogged about the exciting SharePoint integration and how it works. This post is about the exciting new server side SharePoint integration that is now available as part of CRM2013 SP1 Online. There has already been some good posts on how to set up SharePoint sever-side Sync but in this series I'm going to explain how the server to server integration works in more detail and run through some scenarios of how it can be used for custom solutions. CRM List Component Integration Before CRM2013 SP1 was released the only option for SharePoint Integration was to use the CRM List Component. Each document location was surfaced on a record form record via an IFRAME that placed a SharePoint page inside the CRM page via the list component aspx page. This SharePoint page rendering the document library's default view with a CRM theme and provided the upload/download commands.

The CRM form page is displayed in the browser and including an IFRAME that requested the configured document library page from SharePoint. The IFRAME shows the SharePoint document library styled to look like CRM. This required the user to be independently authenticated with SharePoint. Using any of the actions in the page (New/Upload etc.) sends requests directly to SharePoint.

Changing Landscape This approach worked well but since the user was accessing SharePoint directly within the IFRAME they'd sometimes encounter authentication issues where they must be authenticated with SharePoint first and sometimes SharePoint needed to be configured to allow inclusion of content in IFRAMES. In addition to this the list component required a sandbox host to run but this feature is being phased out in SharePoint Online. Server to Server SharePoint Integration (S2S) With the introduction of CRM2013 SP1 a new type of integration has been developed that provides direct server to server integration between SharePoint and CRM thus removing the need for the user to be pre-authenticated with SharePoint on the client.

The Record page includes a standard sub grid that is populated using the CRM entity query object model. CRM converts a RetrieveMultiple request on the SharePoint Document entity into SharePoint CAML (Collaborative Application Markup Language) query and sends it to the SharePoint Web Services. The important part here is that this query is run in the context of the currently logged on user and so they only see the document that they have access to in SharePoint (more on how this works in part 2 of this series). Documents are rendered inside the CRM Form HTML as a standard sub grid in the same way that any other record might be displayed. Using the New/Upload command bar buttons sends a request to CRM by way of an Execute Request in the same way that any other command bar buttons might do. CRM uses the SharePoint Web Service API to execute the requests and refreshes the sub grid.

This server to server integration only works for CRM Online/SharePoint Online combinations that are in the same tenant due to the nature of the server to server authentication and can be turned on in the Document Management Settings using the 'Enable server-based SharePoint integration'. There is a note that states that sandboxed solutions will not be supported in the future for SharePoint online.

Differences between List Component and Server-to-Server Once S2S integration is enabled you'll see a similar view to the list component but it looks far more CRM2013 like. Apart from a slicker interface there are a few other differences: Folder Support The S2S sub grid doesn't support folders within the document library and so all documents are flattened down underneath the document location folder. The Location column does give you folder name which you can sort by to allow grouping by folder. Custom Views The great thing about having the documents queried by CRM is that you can create custom views of documents in the same way you would with any other entity in CRM. When using the list component the default view in SharePoint was rendered in the IFRAME meaning that to get new columns you had to have list customisation privileges on SharePoint such that all users would see the changes. With the new server to server integration you can select SharePoint columns to include in your own views and even add in your own filters using the CRM advance find interface. If you think about it – this is very cool! Item Actions The List Component was by nature very similar to the SharePoint list user interface and so it had more or less full support of actions that can be performed from SharePoint (with the exception of workflow operations). The server to server sub-grid provides all the main functions but with some options such as Alert Me, Send Short Cut, View History and Download a Copy being unavailable. The S2S integration gives the following command bar actions:

This is in comparison to the List Component actions that are as shown below.

Inline Dialogs With CRM2013's single page user experience any pop-out windows are supposed to be kept to a minimum. When using the list component operations (such as check-in/out) a new window would always pop out but with S2S integration an inline dialog shown instead. This really make it feel tightly integrated and slick.

Out of these differences, the lack of folder support is the only one that has had any significant effect on my solutions but actually can be seen as an advantage if using sub-folders to hold child entity documents. In this scenario all documents will be visible from the parent record's document view rather than rely on the user drilling down into each folder to see content. That's all for now but in the next article in this series I'll show you more of how this functionality works under the covers. Read Part 2 @ScottDurow

Polymorphic Workflow Activity Input Arguments

I often find myself creating 'utility' custom workflow activities that can be used on many different types of entity. One of the challenges with writing this kind of workflow activity is that InArguments can only accept a single type of entity (unlike activity regarding object fields). The following code works well for accepting a reference to an account but if you want to accept account, contact or lead you'd need to create 3 input arguments. If you wanted to make the parameter accept a custom entity type that you don't know about when writing the workflow activity then you're stuck!

[Output("Document Location")] [ReferenceTarget("account")] public InArgument<EntityReference> EntityReference { get; set; }

There are a number of workarounds to this that I've tried over the years such as starting a child work flow and using the workflow activity context or creating an activity and using it's regarding object field – but I'd like to share with you the best approach I've found. Dynamics CRM workflows and dialogs have a neat feature of being about to add Hyperlinks to records into emails/dialog responses etc. which is driven by a special attribute called 'Record Url(Dynamic)'

This field can be used also to provide all the information we need to pass an Entity Reference. The sample I've provide is a simple Workflow Activity that accepts the Record Url and returns the Guid of the record as a string and the Entity Logical Name – this isn't much use on its own, but you'll be able to use the DynamicUrlParser.cs class in your own Workflow Activities.

[Input("Record Dynamic Url")] [RequiredArgument] public InArgument<string> RecordUrl { get; set; }

The DynamicUrlParser class can then be used as follows:

var entityReference = new DynamicUrlParser(RecordUrl.Get<string>(executionContext)); RecordGuid.Set(executionContext, entityReference.Id.ToString()); EntityLogicalName.Set(executionContext, entityReference.GetEntityLogicalName(service));

  The full sample can be found in my MSDN Code Gallery. @ScottDurow

Creating a Contact Card List Web Resource with Images

Sparkle XRM provides a great way of creating grids and forms that look and work similar to Dynamics CRM but sometimes you need to create a responsive user interface that is a little different. Luckily there is a wealth of jQuery plugins out there that provide a great starting point. For this post I'm going to show you how to use FreeWall to create a dynamic grid layout of contact cards but the same approach would apply for any other plugin that isn't included in the core Sparkle XRM dependencies library. This sample creates an HTML web resource that lays out your contacts in a responsive grid that resizes depending on the size available.

Create the Script# Import Whenever we need to use an external library from Sparkle XRM, the external API must be defined as imported classes. For FreeWall we must import the jQuery plugin and the configuration options class. Notice that the [ScriptName("Object")] is used on the configuration options so that although our Script# class uses a strongly typed class, the JavaScript compiled uses an anonymous type so as not to create unnecessary class prototypes.

Create the View Model It is a good idea to start with the View Model since this defines all the functionality that the View must expose as well as communicating with the server. For this sample we have a simple view model that simply loads a list of contacts into a list so that FreeWall can be bound to it to display our contact cards. It also provides a function to get the Image Url of the contact and return a placeholder image if no image is defined. The contact image can be found by returning the attribute with logical name 'entityimage_url'

Include the library JS Once you've selected the library you want to use, you'll need to include it in your Crm Solution project under the js folder, and give it a UniqueName and Display Name similar to dev1_/js/freewall.js

Create the HTML View The HTML View should be added to the html folder and must contain the scaffolding to hook the jQuery library into and initialise the View code. The data binding is done using Knockout's built in templating engine using the 'template' binding.

Create the View Class The view class's job is to instantiate the View Model and initialise the binding.

Notice the OnAfterRender call back – this is called every time a new contact card is rendered because of the binding afterRender: Client.InlineSubGrids.Views.ContactCardView.onAfterRender in the HTML. If this is not done then the freewall grid will not layout until the window is resized. The result is a nice and responsive layout that optimises the fill the available space and has variable height blocks.

@ScottDurow

Multi Entity Search for CRM2013

I've just published an update to my Multi-Entity Search Solution (after being encouraged by my friend and fellow Dynamics CRM MVP Gus Gonzalez!). Features:

Search across multiple entities at once. Uses the same configuration as the mobile client 'Quick Find' (Settings->General ->Set Up Quick Find). This allows you to select which entities you would like to search across. Virtual Scrolling with new records loaded as you scroll rather than all loaded at once. Shows the primary entity image of returned records (if there is one) in the search results.

  In the new version you'll find:

A search button added to the top navigation bar* rather than using a Command Bar button. Auto searching as you type the search term Mouse Wheel horizontal scrolling support

*Since there is no supported way of doing this, I've had to do a little DOM shenanigans to get this to work the way Gus wanted!

To try it out you'll need to install the following 2 managed solutions:

SparkleXrm015managed.zip MultiEntitySearch23_managed.zip

If you like this, you might also like to check out my Start Menu Navigation for CRM2013! @ScottDurow

Monitor, Monitor, Monitor

I once heard someone say that "the great thing about Dynamics CRM is that it just looks after itself" Whilst CRM2013 is certainly very good at performing maintenance tasks automatically, if you have a customised system it is important to Monitor, Monitor, Monitor! There are some advanced ways of setting up monitoring using tools such as System Center but just some regular simple monitoring tasks will go a long way for very little investment on your part: 1) Plugin Execution Monitoring There is a super little entity called 'Plugin-in Type Statistics' that often seems to be overlooked in the long list of advanced find entities. This entity is invaluable for tracing down issues before they cause problems for your users and as defined by the SDK it is "used by the Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online platforms to record execution statistics for plug-ins registered in the sandbox (isolation mode)." The key here is that it only records statistics for your sandboxed plugins. Unless there is a good reason not to (security access etc.) I would recommend that all of your plugins be registered in sandbox isolation. Of course Dynamics CRM online only allows sandboxed plugins anyway so you don't want to put up barriers not to move to the cloud. To monitor this you can use advanced to show a sorted list by execution time or failure count descending:

If you spot any issues you can then proactively investigate them before they become a problem. In the screen shot above there are a few plugins that are taking more than 1000ms (1 second) to execute, but their execution count is low. I look for plugins that have a high execution count and high execution time, or those that have a high failure percent. 2) Workflow & Asynchronous Job Execution Monitoring We all know workflows often can start failing for various reasons. Because of their asynchronous nature these failures can go unnoticed by users until it's too late and you have thousands of issues to correct. To proactively monitor this you can create a view (and even add to a dashboard) of System Jobs filtered by Status = Failed or Waiting and where the Message contains data. The Message attribute contains the full error description and stack trace, but the Friendly message just contains the information that is displayed at the top of the workflow form in the notification box.

3) Client Latency & Bandwidth Monitoring Now that you've got the server-side under control you should also look at the client connectivity of your users. There is a special diagnostics hidden page that can be accessed by using a URL of the format: http://<YourCRMServerURL>/tools/diagnostics/diag.aspx As described by the implementation guide topic, "Microsoft Dynamics CRM is designed to work best over networks that have the following elements:

Bandwidth greater than 50 KB/sec Latency under 150 ms"

After you click 'Run' on this test page you will get results similar to that shown below. You can see that this user is just above these requirements!

You can read more about the Diagnostic Page in Dynamics CRM. You can also monitor the client side using the techniques I describe in my series on Fiddler:

Part 1: X-Ray vision Part 2: Invisibility Part 3: Faster than a speeding bullet! Part 4: Ice Man

If you take these simple steps to proactively monitor your Dynamics CRM solution then you are much less likely to have a problem that goes un-noticed until you get 'that call'! @ScottDurow

My top 3 fixes in CRM2013 SP1

There are great many new features shipped in CRM2013 SP1 but let's not forget there are some eagerly awaited fixes as well (as described by http://support.microsoft.com/default.aspx?kbid=2941390) Since there has already been plenty of coverage of the new features, I thought I would pick out my top 3 fixes that I've been particularly waiting for…Queue up the charts count-down soundtrack!

In at Number 3: Matching Connection Roles Connections are a great way of providing users with an overview of a contact's involvement with all areas of your business. Right from within a contact record users can see the roles that the contact has across different record types such as accounts, cases, and opportunities. Roles are specified on each side of the connection and in many cases you need to have the same role on both sides. In CRM2011 this was possible but strangely with CRM2013 the same role could not be specified as the matching role with the issue being described by the KB article as "In Microsoft Dynamics CRM 2013, users are unable to set a Matching Connection Role to the same Connection Role." Up until now the work around was to create a different role but with the same name but I've tested this in SP1 and I'm pleased to report that it now works the same as it did in CRM2011. New at Number 2: Importing solution fails when plugins attached to custom actions The addition of custom actions to CRM2013 was fantastic for creating custom server logic that is called from JavaScript. Unfortunately when you attached a plugin to a custom action message and imported a solution containing that plugin it would fail (See the Microsoft Connect article for this issue). I have held back from using this feature up until now due to the pain it created during deployments but now that it is fixed in SP1 I'm going to be making a lot more use of Custom Action plugins! UPDATE: Actually, the connect item for this issue is not entirely correct - this will be fixed in one of the next Update Rollups of CRM 2013 SP1 …and this Service Pack's Number 1 Fix is: "Found more than one RibbonDiff entity" This message is likely a very familiar message to anyone who has made customisations to the Ribbon with CRM2011 (as described by http://support.microsoft.com/kb/2503029). The message was shown when importing customisations and was usually down to there being more than one element in the ribbon xml that had been given the same ID. When CRM2013 was released the message started popping up far more frequently. Initially I was worried it was due to an issue with Ribbon Workbench but eventually I tracked it down to the fact that elements were being duplicated when a solution was exported from CRM2013. The Ribbon Workbench resolves duplicate IDs automatically so the issue only caused problems when transferring a solution between environments through an export/import but what was more confusing is that the issue would only happen on the second import. There is a line in the KB article for SP1 that describes the issue as: "When we import, the import logic creates two values for each entry within the RibbonDifBase. But When we export the application ribbon we do not have any check for this and we export 2 values directly from the DB to the XML. This if imported to a new org will create 4 values in the table RibbonDiffBase. If the solution is imported again to the same org causes an error" The Microsoft Connect item for this issue is still marked as active but I've tried to reproduce the issue in SP1 and so far so good! Well done Dynamics CRM Product team! Poptastic! @ScottDurow

And then there were seven!

If you've updated to the CRM2013 Spring '14 Wave (Service Pack 1) I think you'll agree that it contains some pretty awesome features. You can read a good roundup of the developer features in the SDK (http://msdn.microsoft.com/en-us/library/gg309589.aspx#BKMK_NewInSpring2014) but have you noticed that there is a little less white space across the top of your forms? This is because the Command Bar now shows 7 rather than 5 buttons before buttons are added to the ellipses overflow.

It is worth noting that the number of buttons that are displayed before the overflow is not (yet?) configurable and nor can you revert back to displaying only 5 (pre SP1). That said, I really appreciate this little change that is a result of the product team listening to feedback from users. What's more it has no impact on the Ribbon Xml or Ribbon Workbench.

You might like to read more about the Command Bar in my post from way back when CRM2013 was first released. @ScottDurow

Create a command bar button for your custom activities

When creating a new custom activity entity you are presented with a great many checkboxes to choose from. One of these checkboxes is 'Display in Activities Menus' that will ensure that the activity type is included in the Activities Menu on records

The Custom Activities flyout menu is a dynamically generated menu so that if you load up an entity in the Ribbon Workbench and expand this button you won't see any menu items. This has been the subject for confusion for users who are trying to move this button out of the sub menu and put it on the main Command Bar as a short cut for uses. Since the menu is created dynamically at run time there is no button to customise and move. This post shows you how to create a custom activity button on the opportunity form. 1. Determine the Entity Type Code of your custom activity. Each custom entity has an Entity Type code. This integer value is different to the entity logical name and could be different on each organization you deploy your solution. We need to know this entity type code in order to create a new record of a specific entity type. To find the value, create a new record for your custom entity in Internet Explorer and press Ctrl-N (opens a new window with Url visible) and copy the URL. This should look something like: http://server/Org/main.aspx?etc=10005... You need to note the etc number for later. 2. Install Ribbon Workbench You'll need to install the Ribbon Workbench as described by 'Getting started with the Ribbon Workbench' 3. Create and open a solution containing the Opportunity Entity The Ribbon Workbench requires a solution to load that contains the entities that you wish to work on. Since we are adding the new button to the opportunity entity, add it to the solution – only add the entities you need to speed up the solution load/publish time. When you first open the Ribbon Workbench it will allow you to select your new solution. 4. Click on the 'Ribbon' tab and change drop down in the top right to 'Form' We need a template command to use and so we select the 'Ribbon' view rather than the Command Bar view so to locate the 'Task' button on the Form ribbon. 5. Select the 'Add' tab and then right click on the 'Task' button and select 'Customise Command' The Task button is located on the 'Add' tab. Using 'Customise Command' creates a copy of the add task command that we can change to reference our custom acitivty. 6. Expand the Commands node to see the customised command and select 'Mscrm.AddTaskToPrimaryRecord'.7. Rename the command to be something like 'Mscrm.AddCustomActivityToPrimaryRecord' By renaming the command we are creating a new command specifically for our new button, rather than customising the existing one. 8. Expand the Command and JavaScript command and change the Int value to be the Entity Type Code of your custom activity Remember that the entity type code is unique to your custom entity – but it could change between deployments.

  1. Right click on the command and select 'Edit Display Rules' and Remove the 'HideOnCommandBar' rule Since the Task button only shows on the legacy ribbon, we need to change the command so it also shows on the command bar by removing this display rule.

  2. Select the 'Command Bar' tab and drag a button onto the Form command bar

  3. Set the Command to be your new custom command (e.g. Mscrm.AddCustomActivityToPrimaryRecord)
  4. Set the image16 to be /imgs/ribbon/AddActivity16.png (or a custom image you have for your entity)

  5. Expand the 'Display Rules' and set the 'IsCore' property to 'True' on each Display Rule.

  6. Expand the 'Enable Rules' and set the 'IsCore' property to 'True' on each Enable Rule. By setting the 'IsCore' property to true, we only reference them rather than redefining them.
  7. Publish your customisations
  8. Test the new button on the opportunity form!

Fiddler2: The tool that gives you Superpowers – Part 3

This post is the third post in the series 'Fiddler – the tool that gives you superpowers!'

Part 1: X-Ray vision Part 2: Invisibility Part 3: Faster than a speeding bullet! Part 4: Ice Man

Faster than a Speeding Bullet If you have done any development of Web Resources with Dynamics CRM then I'm certain that you'll have become impatient whilst waiting to first deploy your solution and then publish it before you can test any changes. Everytime you need to make a change you need to go round this loop which can slow down the development process considerably. Using the Auto Responders I described in my previous post (Invisibility) you can drastically speed up this development process by using Fiddler to ensure changes you make to a local file in Visual Studio are reflected inside Dynamics CRM without waiting for deploying and publishing. You make the changes inside Visual Studio, simply save and refresh your browser and voilà! Here some rough calculations on the time it could save you on a small project:

Time to Deploy

15

seconds

Time to Publish

15

seconds

Debug iterations

20

 

Number of web resources

30

 

Development Savings

5

hours

Time to reproduce live data in test/development

1

hour

Number of issues to debug in live

10

 

Testing Savings

10

hours

     

Total Savings for small project

15

hours

  What is perhaps more important about this technique that it saves the frustration caused by having to constantly wait for web resource deployment and ensures that you stay in the development zone rather than being distracted by the latest cute kitten pictures posted on facebook! Do remember to deploy and publish your changes once you've finished your development. It seems obvious but it is easily forgotten and you're left wondering why your latest widget works on your machine but not for others! More information can be found on this at the following locations:

http://www.sparklexrm.com/s/Tutorials/SetUpNewProject.html http://blogs.msdn.com/b/devkeydet/archive/2013/08/14/debugging-crm-web-resources-without-ever-deploying-them.aspx

Read Part 4 - Ice Man! @ScottDurow

Fiddler2: The tool that gives you Superpowers – Part 4

This post is the fourth and final post in the series 'Fiddler – the tool that gives you superpowers!'

Part 1: X-Ray vision Part 2: Invisibility Part 3: Faster than a speeding bullet! Part 4: Ice Man

Ice Man Perhaps Ice Man is the most tenuous super power claim but it's regarding a very important topic – HTTP Caching. Having a good caching strategy is key to having good client performance and not over-loading your network with unnecessary traffic. Luckily Dynamics CRM gives us an excellent caching mechanism – but there are situations where it can be accidently unknowingly bypassed:

Not using relative links in HTML webresources Loading scripts/images dynamically without using the cache key directory prefix Not using the $webresource: prefix in ribbon/sitemap xml.

Luckily we can use Fiddler to keep our servers running ice cold by checking that files that are not being cached when they should be. There are types of caching that you need to look for: Absolute expiration These web resources will not show in Fiddler at all because the browser has located a cached version of the file with an absolute cache expiration date and so it doesn't need to request anything from the server. By default CRM provides an expiration date of 1 year from the date requested, but if the web resource is updated on the server then the Url changes and so a new version is requested. This is why you see a request similar to /OrgName/%7B635315305140000046%7D/WebResources/somefile.js. Upon inspection of the response you will see an HTTP header similar to:

HTTP/1.1 200 OKCache-Control: publicContent-Type: text/jscriptExpires: Tue, 14 Apr 2015 21:18:35 GMT

Once the web resource is downloaded on the client it is requested again until April 14 2015 unless a new version is published where CRM will request the file using a new cache key (the number between the Organization name and the WebResources directory). You can read more about this mechanism on my post about web resource caching. ETAG Cached files These resource are usually images and static JavaScript files that are assigned an ETAG value by the server. When the resource changes on the server it is assigned a different ETAG value. When the browser requests the file it sends the previous ETAG value if it hasn't been modified then the server responds with a 304 response meaning that the browser can use the local cached file. Files that use ETAG caching will show in grey in Fiddler with a response code of 304: During your web resource testing it is a good idea to crack open Fiddler and perform your unit tests – you should look for any non-304 requests for files that don't need to be downloaded every time they are needed. Another way to ensure that your servers are running cool as ice is to look at the request execution length. Occasionally code can be written that accidently returns much too much data than required - perhaps all attributes are included or a where criteria is missing. These issues don't always present themselves when working on a development system that responds to queries very quickly, but as soon as you deploy to a production system with many users and large datasets, you start to see slow performance. There are a number of ways you can test for this using Fiddler: Visualise Request Times The order in which your scripts, SOAP and REST requests are executed in can greatly affect the performance experienced by the user and so you can use Fiddler's Time line visualizer to see which requests are running is series and which are running in parallel. It also shows you the length of time the requests are taking to download so that you can identify the longest running requests and focus your optimisation efforts on those first.

  Simulate Slow Networks If you know that your users will be using a slow network to access CRM or you would just like to see how the application responds when the requests start to take longer because of larger datasets you can tell fiddler to add an artificial delay into the responses. To do this you can use the built in Rules->Performance->Simulate Modem Speeds but this usually results in an unrealistically slow response time. If you are using Auto Responders you can right-click on the Rule and use set Latency – but this won't work for Organization Service/REST calls. The best way I've found is to use the Fiddler Script: 1) Select the 'Fiddler Script' Tab 2) Select 'OnBeforeRequest' in the 'Go to' drop down 3) Add the following line to the OnBeforeRequest event handler.

This will add a 50 millisecond delay for every kB requested from the server which assuming there was no time server time would result in ~160 kbps downloads. If you've not used Fiddler for your Dynamics CRM Development yet I hope these posts are enough to convince you that you should give it a try – I promise you'll never look back! @ScottDurow