Friday, July 24, 2015

A bookmarklet to open a entity by Guid in Dynamics CRM

So I colleague of mine passed me a number of CRM 2013 bookmarklets that do all sorts of things, like showing the guid of the entity, enabling all fields, removing the business required attribute, etc. The 'god mode' one is the most fun.

Anyway, I decided to write one of mine: a bookmarklet that enables you to open an entity using it's guid. Unfortunately, right now, I ask that you also give me the entity name, but other than that, it's pretty useful while debugging applications that make extensive use of the SDK.

So, without any more delays: get it here.

If you are curious, you can check the bookmarklet code below.

javascript:var entity = window.prompt("Enter the name of the entity to open the default form for:", "");var guid = window.prompt("Enter the guid of the entity to open thedefault form for:", "");var o = new Object(); o.uri = "main.aspx?etn=" + entity + "&pagetype=entityrecord&id=%7B" + guid + "%7D";window.top.document.getElementById("navBar").control.raiseNavigateRequest(o);

Here's the same code block in a more readable way:

javascript:
var entity = window.prompt("Enter the name of the entity to open the default form for:", "");
var guid = window.prompt("Enter the guid of the entity to open thedefault form for:", "");

var o = new Object(); 
o.uri = "main.aspx?etn=" + entity + "&pagetype=entityrecord&id=%7B" + guid + "%7D";
window.top.document.getElementById("navBar").control.raiseNavigateRequest(o);

Tuesday, July 7, 2015

USD: Default Actions In Hosted Controls

While I don't find time to do a proper introduction over Unified Service Desk, Microsoft's platform for the development of call center systems, I'll keep bringing some nice-to-know-facts about it.

Custom Hosted Controls

A custom hosted control is basically a WPF UserControl specialized to wire-up against USD's internal engines. To develop it, you can download and install the UII SDK and the Visual Studio Extension that contains the templates for it. Or you can do it the hardcode way, which I prefer, and simply install a USD nuget:

PM > Install-Package Microsoft.CrmSdk.USD.CoreAssemblies
Once that's done, simply create a new WPF UserControl and change it's base class to DynamicsBaseHostedControl:

< dynamics:dynamicsbasehostedcontrol x:class="MyLib.Controls.Views.FooView" 

                                        xmlns:dynamics="clr-namespace:Microsoft.Crm.UnifiedServiceDesk.Dynamics;assembly=Microsoft.Crm.UnifiedServiceDesk.Dynamics"
                                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >

Nice! Now you can start developing you own USD control.

Actions and Action Calls

There are only two reasons to actually create DynamicsBaseHostedControl controls. One is to access the USD Context, the other is to wire up Actions and Events.

Microsoft's documentation over Action and Events is surprisingly good, so it's worth to check out. But it fails to talk about how to develop using action and events. I'll probably address this more comprehensively in the coming posts, but, for now, let's just focus on how to create custom actions that you can call from other controls.

In your DynamicsBaseHostedControl, override the method DoAction:

protected override void DoAction(RequestActionEventArgs args)
{
    switch (args.Action)
    {
        case "ActionName":
            DoSomething();
        break;
        
        case "AnotherAction":
            DoSomethingElse();
        break;

            // (...)
    }

    base.DoAction(args);
}

The args contain everything you should need to implement that call:
  • Its property Action contains the name of the action that was called.  You should switch on it.
  • Its property Data contains the parameters that were sent with the action call
[as you can see from above, USD unfortunately suffers from String Obsession (a common kind of Primitive Obsession), since it's heavily based on parametrization]

Now, the call to base.DoAction is very important: every DynamicsBaseHostedControl implements a few standard actions. Microsoft documentation on this is very thin (as is on everything USD), but at least these actions are implemented:
  • new
  • new_crm_page
  • open
  • open_crm_page
  • popup
  • close
  • fireevent
  • movetopanel
  • setsize
If you don't call the base, you are effectively disabling all these standard behaviors. But here's the grand finale and the reason for this post: USD won't warn against unknown actions, so if you send the action "foobar" against it, it will not reject, only log it. You can imagine what this means in practice: a typo can cause all sorts of pain. So, be wary when dealing with actions.

Friday, June 26, 2015

Sometimes a Gem: How to investigate/debug Microsoft Fakes build error

So I was having a d@%n issue with VS2015, which was refusing to create a fake stub for me, with the not-helpful-at-all error "failed to generate stub type for type (...)". Nothing in the build output log, nothing anywhere to explain what was going on.

Google has never been so unhelpful, which is to say, he helped me only at the fourth or fifth entry.

This post includes a gem:

To debug the build issue, open the assembly.fake xml file in the Fakes folder added automatically to your project. Add the two parameters Diagnostic=”true” Verbosity=”Noisy” to the fake element, like this:
(...)

Then in Tools|Options under Projects and Solutions|Build and Run, change the MSBuild project output verbosity to ‘Diagnostic’. Build again and in the generated output, look for Task “GenerateFakes” 

It worked like a charm. Thanks David!


Tuesday, June 16, 2015

Name a file or folder with a starting dot

So, in linux hidden folders and files begin with a dot. In windows, it was considered forbidden to create such files (at least I believed it so in FAT32), but now you can see a number of tools creating file system entries with that naming scheme (git, for instance). But, as a user, can I name anything like that?

Let's try to create a folder that is dot-starting:

Sexy naming
The result is not what we wanted:

Type a filename, it says. We just did, dummy!

Well, Windows think we didn't typed a name. That's scary, we did! Or, maybe not? For Windows, it seems, everything after the dot is considered an extension, so, in this case, we just provided an extension for the file (not a name).

To go around this issue, you have to make windows understand that ".dotstarted" is the name, not the extension. And what is the extension in this case, you may ask? The empty string, of course. So, the full name, with the extension, would be...

File with extensions

We just specified the empty string as the extension, making sure Windows understands the ".dotstarted" part as the name. This results on it being correctly created, be it a directory or a simple file. 

Sunday, May 17, 2015

Remove All Nugets From All Projects

This may never be used in your usual conditions, however, I found it to be useful at least once: NuGet packages got messed up after some merges, with different versions in different projects. So I wrote a one-liner to remove all the packages from all the projects in the solution.

All you have to do is paste this snippet into the Package Manager Console.

Get-Project -All | %{ $projectName = $_.ProjectName; foreach($package in Get-Package -ProjectName $projectName) { Uninstall-Package -ProjectName $projectName -Id $package.Id -Force }}


All thanks to this reference.