•   Posted in: 
  • CRM

Do you know what the selected option below is:

Untitled

Until I starting playing with Azure and discovered that CRM has built in functionality to send messages to the Azure Service Bus (i.e. this) I didn’t even give it a moments thought. This option in the CRM plugin registration tool is the entry point to getting your solution talking to Azure and opening up some new and exciting opportunities.

In this post, I will quickly run through how to register a new service endpoint, which is a little bit more complex then just clicking the highlighted option. This will include how to create the service bus in Azure. In a later post I will discuss what you can do with this once it is up and running.

First up, you need to create the service bus in Azure. If you don’t already have an Azure subscription jump on to azure.microsoft.com and sign up for a free trial. For this example we will use a Queue, but there are several other options that you can use as well, each provides different capabilities. I won’t screen shot every step, but this is a simple case (as of the time of this post – Azure may change all of this in the future) of clicking on the following:

  1. + NEW
  2. APP SERVICES
  3. SERVICE BUS
  4. QUEUE
  5. CUSTOM CREATE
  6. Specify Queue Name, Region and either use existing or create a new namespace
  7. Configure the queue with the options you want.
  8. Make sure Enable Partitioning is unticked, otherwise you won’t be able to use it with CRM
  9. Click the tick icon down the button to accept

Azure will then go away and in a minute or two finish creating and activating your service bus.

Next up, we need to get the connection information to plug into CRM and get it talking to your new service bus. To get this information you need to select the service bus (note: there is a difference between selecting the service bus and going into it and seeing the queues, you need to click on a column other than the Namespace Name to select it) and click CONNECTION INFORMATION at the bottom of your screen. All you need from this screen is the default key and they provide a copy button beside it if you are too lazy to select and copy it yourself.

Now we can get back to that initial image. Connect the plugin registration tool to your CRM organisation and hit Register New Service End Point:

image

In this screen fill in:

  1. Name: the name you want to call this connection
  2. Description: an optional description of what this is for
  3. Solution Namespace: the name of the service bus namespace you created or used in Azure above
  4. Path: the name of the queue you created above
  5. Contract: Queue (for this example at least)
  6. Claim: None
  7. Federated Mode: Unticked

Then click Save & Configure ACS and you should see this screen:

image

Fill in:

  1. Management Key: The default key you copied from the connection information screen in Azure earlier 
  2. Certificate File: In CRM browse to Customizations, Developer Resources (or just click the link in the dialog shown above), download the certificate and browse to where you downloaded it
  3. Issuer Name: You will find this in the same place as the certificate. Should be something along the lines of crm.dynamics.com or crm5.dynamics.com depending on your region.

Then click Configure ACS and if everything goes well, close the dialog, save and verify, save again and you are done. You should now have a brand new service endpoint configured in CRM. This will not do anything yet, but in my next post I will show you some things you can try. The CRM SDK is also a great source of sample code to carry on from this.

  •   Posted in: 
  • CRM

Note: The following is based/extended from the recent blog entry by Jared Johnson over at Magnetism Solutions: Bookmarklets to aid Microsoft Dynamics CRM 2013 Development – Thanks for the tip

Navigating around CRM, in particular the new user interface in CRM2013, can be slightly annoying at times. Especially for developers and customisers who are not exactly using the system as it is designed for end users. As power users we often need to get to parts of the system that are behind the scenes (such as customisations and solutions) or get information out of the system that end users don’t need to know or care about (such as record GUIDs). In the past, I have achieved this by making bookmarks to solutions (i.e. absolute URL to a solution for a specific organisation, which is useless once I am no longer working on that project) or by opening up the developer tools in my browser and writing some javascript to tease out the information I need. However, finding the id of a record by typing “Xrm.Page.data.entity.getId()” over and over again, fixing typos, dealing with how each browser handles the iFrames in CRM and all the other nuances involved can get very tedious.

In the post linked above, Jared suggests a better way: using javascript in bookmark (or Bookmarklets). Below is a list of the bookmarklets I have added to my virtual toolkit, based on his post and some additions of my own. These work (on my machine) in IE, Firefox and Chrome and on any CRM organisation I have tried, but I don’t provide any guarantees.

Disclaimer: these are not necessarily supported approaches to interact with CRM so there is always the potential for future updates to break them or cause them to behave differently. It is recommended you understand what they are doing before you copy, paste and use them blindly.

GetId()

javascript: try{if (window.prompt("ID:", $("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.data.entity.getId().slice(1, -1))) { }}catch(e){}

Pops a dialog box with the id of the current record (braces removed) selected for you to easily copy and do whatever you need with it.

Capture

RefreshData()

javascript:try{$("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.data.refresh()}catch(e){}

Reloads the data on the current form, without refreshing the whole page so is much quicker. Useful if you know the data on the server has changed and you want to see this reflected in your browser and would rather not have the whole page reload and break back history, trigger code etc.

Capture2

OpenAdvancedFind()

javascript:try{open($("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.context.getClientUrl() + "/main.aspx?pagetype=advancedfind")}catch(e){}

Opens advanced find for the current organisation in a new window/tab. Useful for when you are on a record or other page within CRM where Microsoft has decided an advanced find button isn’t necessary.

image

GoToSolutions()

javascript: try{var o = new Object(); o.uri = "/tools/Solution/home_solution.aspx?etc=7100&sitemappath=Settings|Customizations|nav_solution"; window.top.document.getElementById("navBar").control.raiseNavigateRequest(o); void (0)}catch(e){}

Navigates you to Settings > Solutions. Note: the back button will work from here and take you back to the previous page. This should be self explanatory and saves a few clicks. The code above should be easy to modify to navigate somewhere else.

image

OpenDefaultSolution()

javascript:try{open($("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.context.getClientUrl() + "/tools/solution/edit.aspx?id=FD140AAF-4DF4-11DD-BD17-0019B9312238")}catch(e){}

Opens a new window/tab with the default solution of the organisation for you to view or customise. This script dynamically creates the URL for the default solution based on the client URL and the fact that the default solution has a the same ID for all CRM organisations (see:Constant SolutionId Values).

That is all I have for now, but I’m sure that there are many other ideas out there on how to leverage this. I will most likely find others myself as I use these and think about it further, particularly around the raiseNavigateRequest method. If so, a follow up to this post will be in order.

To set the scene, say you are developing a solution for CRM2013 using the Developer Toolkit for Microsoft Dynamics CRM in Visual Studio and wanting to create a asynchronous plugin step. Easy right? Open CRM Explorer, find the entity, add a plugin, fill in the details, set it to run asynchronously and you are away. However, those of you that have used the plugin registration tool will know that there is a pretty handy option when Registering a Step that lets you tell CRM to Delete AsyncOperation (i.e. system jobs) if the StatusCode = Successful:

Register New Step dialog

This is great because it means your system jobs table doesn’t get clogged up with entries when things are going fine. Instead it just tracks when you probably need to look into something. So how do you go about doing this in Visual Studio?

I was in this situation this week and found (let me know if I missed something obvious here) that this isn’t an option using the UI for the developer kit and there is no documentation (that I can find, nothing in the SDK and Google didn’t help me) on how to set this. I considered giving up and having this as an extra step to manually do after deploying the solution, which would be a pain, but decided to spend a bit more time and dig deeper. I decompiled the assembly for the developer toolkit (using dotpeek for those interested) and found that this is a supported, but not advertised option for the step in the RegisterFile.crmregister xml file within the CRMPackage project. All you need to do is add AsyncAutoDelete="true" attribute to the asynchronous step tags(s) in the XML, deploy and you are away laughing.

For example, your RegisterFile.crmregister will end up looking something like this:

<?xml version="1.0" encoding="utf-8"?>
<Register xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/crm/2011/tools/pluginregistration">
   <Solutions>
       <Solution Assembly="Plugins.dll" Id="2318c739-68d9-d896-8cf1-6c3be5a8c238" IsolationMode="Sandbox" SourceType="Database">
           <PluginTypes>
               <Plugin Description="Contact Plug-in" FriendlyName="ContactPlugin" Name="Plugins.ContactPlugin" Id="2618c739-68d9-d896-8cf1-6c3be5a8c238" TypeName="Plugins.ContactPlugin">
                   <Steps>
                       <clear />
                       <Step AsyncAutoDelete="true" CustomConfiguration="" Name="Plugins.ContactPlugin.PostContactUpdate" Description="Post-Operation of Contact Update" Id="92a843f0-68d9-d896-8cf1-6c3be5a8c238" MessageName="Update" Mode="Asynchronous" PrimaryEntityName="contact" Rank="1" SecureConfiguration="" Stage="PostOutsideTransaction" SupportedDeployment="ServerOnly">
                           <Images />
                       </Step>
                   </Steps>
               </Plugin>
           </PluginTypes>
       </Solution>
   </Solutions>
   <XamlWorkflows />
</Register>

While it would be nice to achieve this from the UI, something we might see in a future update, this is at least a pretty simple solution to work with for now.