Author Archives: Alex Shlega

Invalid User Authorization error

Was trying to enable data encryption in Dynamics and the next thing I knew there was an error message:

image

Invalid User Authorization

The user authentication passed to the platform is not valid.

It’s a rather vague message to say the least, so a quick google search revealed some links but no definitive answers. Lucky for me, this error was happening in the on-premise environment (although, where else would I need to enable the data encryption, right?) Even more, it was happening on my virtual machine, so I had full access..

Turned out the error message showing up in the windows event log on the CRM server was different, and, actually, much more useful:

Exception information:

Exception type: CrmException

Exception message: HTTPS protocol is required for this type of request, please enable HTTPS protocol and try again.

Now that’s straightforward. Yes, I did not have HTTPS..

Dynamics Portals: Aligning field labels to the left

 

When designing a form in Dynamics, we can specify, for each section, how field labels will be aligned. It does not seem to have any effect on how those labels show up on the portal, though, since they would always be displayed on top of the fields:

image

So how do we change label alignment so they that they move to the left? In other words, how can we achieve this:

image

Turned out it’s doable, and I’ll explain how. It might or might not be the best way of doing this, but it works.

First of all, have a look at this article by Andre Margono – it will explain why I had to apply my customizations via the portal itself rather than in Dynamics:

https://community.dynamics.com/crm/b/workandstudybook/archive/2018/01/08/dynamics-365-portal-when-the-custom-css-won-t-load

Actually, if you know why it would not work when done in Dynamics.. drop me a note.

Anyway, here is what I had to do:

  • I knew I had to apply different css styles, so I had to figure out the styles
  • Once I knew what the style are, I had to apply them to that particular section above (so the other sections still have “top” alignment for the labels)
  • The only way I was able to do it is by adding some javascript to the form that would find the section and apply updates style to the controls in that section

Here is the script:

$( “table[data-name|=’CONTACT_INFORMATION’]” ).find(“.control”).css(“clear”,”none” );
$( “table[data-name|=’CONTACT_INFORMATION’]” ).find(“.control”).css(“float”,”right” );

CONTAT_INFORMATION is the name of the section – you can find in Dynamics when looking at the section properties:

image

The rest is all about finding the table for that section and updating control styles. If you wanted to see the HTML structure, just use F12 option on any of the portal forms and see how they look like on the inside.

Now, thanks to that article by Andre Margono above, I quickly realized that I have to add that script to the form through the portal – somehow those updates were not coming through when done in Dynamics. Here is what I did:

Navigated to the page and opened the editor:

image

Used Options tab to add custom javascript (see above for the script code):

image

Hit the “Save” button, and here we go – for that section only, the labels are, now, left-aligned:

image

Failed to Generate Excel: An error occurred

I was trying to export data to an excel spreadsheet earlier today and ran into something that I have not seen before:

Failed to Generate Excel

An error occurred when Dynamics 365 tried to generate the Excel file. If this problem persists, contact your system administrator.

image

This was happening on a seemingly innocent view which had lots of columns in it. And, as you can see from the screenshot above, there is not a lot of additional information I was able to find in the log file (since there was no log file).

Was it about the total number of columns? Was it something else? It could not be because of the large data set since I did not have that much data..

What you see on the screenshot below is a reproduction:

image

There are only a few columns in the view, but if you try to export data to excel from that view, you’ll get exactly the same error. The same will happen if you try to download an excel template using that view.

Notice how there are two different fields with the same display label in that view. That’s exactly what was causing the error – changing the display label for one of the fields so that display labels become unique in the view solves the problem:

image

Using GetAttributeValue – same result, different meaning. Depending on the context

 

We can use entity[“<attributeName>”], or we can use entity.GetAttributeValue<T>(“<attributeName>”)

The second option won’t produce an exception if the attribute is missing – it will return null instead. It will also return null if the value of that attribute is, actually, null. This may look all right, but there is a difference. So when does it matter?

Imagine these two scenarios:

 

image

In the first scenario, we would query an entity from Dynamics using the OrganizationService, we would ask for a specific attribute, and, then, we would not get it in the result if it’s null. GetAttributeValue would give us null, which is fine since we know how to interpret that result.

In the second scenario, we would have a “Target” entity from the plugin context. However, that entity won’t have any of the attributes that were not submitted from the client. We can still call GetAttributeValue, and it will still return null for such attributes, but we would not be able to say if an attribute just was not provided or if the value was, actually, cleaned up, and “null” is what’s being set (imagine a whole number field which had some value, then the user emptied that field control and hit save). This is when, if you wanted to know exactly what’s happening, it may be better to use Entity.Contains(“<attributeName>”), and, then, compare the value to null (Entity[“<attributeName>”] == null)

Dynamics: how process duration is calculated

 

When looking at the BPF-enabled entity in Dynamics, we can see process duration there – here is an example:

clip_image002

In case you were wondering how the duration (“18 days, 1 hour” in this example) is calculated, here is a diagram:

clip_image004

If the process is still active, what will show up in the duration area is simply the difference between current date and process “Created On” date.

If the process has been aborted or finished, what will show up is the difference between process “Completed On” date and process “Created On” date.

It’s also worth mentioning that “Duration” field on the Business Process Entity will only be populated once the process has been either completed or aborted. For the active processes, that column will be empty:

image

 

And below are some screenshots from Google dev tools where you can see how the calculations are happening in javascript.

Analyzing process status (Completed/Aborted/Active) – this function is setting $v_2 property to be used later

clip_image006

Creating duration text(this function is using $v_2 property from the above

clip_image008

clip_image009

Calculating process duration (get_bpfINstanceActiveFor and get_bpgInstanceCompletedIn are utilized in the code above)

clip_image011

$1i_0 and $29_0 for the code above (the former is set to createdOn, and the latter is set to completedOn)

clip_image013

XperiDo trial – displaying related records in your documents

One of the main problems with the out of the box word templates in Dynamics is that we can’t really use lists. Well, we can add a repeater, but we cannot sort those lists. And, if we cannot sort them, they are becoming somewhat useless once there are more than a few related records in the list.

This, it seems, is one area where ExperiDo can certainly do more.

For example, on the screenshot below I have 148 contacts linked to the A. Datum account:

image

Most of them I just imported using an excel spreadsheet, and those are all “Test Test” contacts. But, depending on the sort order, this list will display different contacts at the top – compare it with the screenshot below:

image

This is something we can actually do with XperiDo:

image

image

Now when I go back to Dynamics to create the document, I get all 148 contacts sorted in the right order:

image

image

XperiDo – starting the trial

Before I continue.. I’m not affiliated with XperiDo, and I’m pretty sure they have no idea I am writing this blog post right now. Still, I was looking for a document generation solution, and, since XperiDo seems to have some interesting features, figured I’d try it a few days ago:

https://www.xperido.com/support/blog/microsoft-dynamics-crm-2016-document-generation-vs-xperido

Not pretending to be an expert in XperiDo, I’ll just share a couple of observations which may help you get up and running a bit faster if you do decide to try it as well:

1. When you get a trial, you get a combo: Dynamics Trial & XperiDo trial

   Yes, they are actually going to set up the whole environment for you. You can opt out of that if you want to try XperiDo with your own Dynamics instance, but I think it’s worth doing a trial in the isolated environment, especially since you’ll be getting a bunch of pre-configured templates as part of the set up.

2. XperiDo installs an add-in for Word –  you can use that add-in to design document templates

  However, make sure to install correct version (64 bits or 32 bits) and all the prerequisites. If you still can’t see XperiDo ribbon after that (other than those 3 buttons on the screenshot below):

image 

Try starting Word “as administrator” – that’s what solved the issue for me when everything else failed:

image

May also need to keep this in mind later since, every now and then, Word will open normally (there are other places you can open it from to edit the templates), and you won’t see the ribbon.

If none of that helps, try contacting XperiDo – you will likely get a follow-up email from their sales shortly after your trial starts, so you can just reply to that email. They do answer (although, I’m not sure how much effort XperiDo would really want to put into the “trial” support).

Why is it that every organization wants to have a unique client portal?

Isn’t it a legitimate question? If we look at it from the client perspective?

Personally, I don’t want to deal with a unique portal every time. I would rather have a single portal with all-familiar interface, with single sign on, and with all the details from various credit cards, banking accounts, loan accounts, tax account, cell phone accounts, internet accounts, and whatever other accounts being collected in one place.

Pretty sure I’m not alone in that.

And I understand that, traditionally, client portals are implemented as part of the organization web site for all the right reasons (branding, marketing, upsell, etc), but it just creates so much havoc. Different statement formats, different payment methods, different logins and passwords, different support channels..  When all I need is one portal where I can see all my information – pretty sure it should be possible to create such a thing (even if it were a paid subscription, I think many of us, “clients”, might agree to pay a small monthly fee for the convenience of having all that info in one place).

But how do you turn this ship around now when pretty much every organization has already invested into the development of their own portal?

Custom indexes and solution upgrades

In the on-prem version of Dynamics, we can create our own custom indexes. And, even though it’s a supported customization (here is a reference: https://msdn.microsoft.com/en-us/library/gg328350.aspx ), there is at least one scenario which may fail.

Basically, the problem is that custom indexes are not managed by Dynamics, so what it means is that any operation which is conflicting with such an index will fail.

For instance, when applying a solution upgrade to a managed solution, and when updated version of that managed solution does not have a field on which there is, already, a custom index, you will see this error in Dynamics:

image

The dreaded SQL Server Error..

In my case, this error occurred because of the custom index:

image

Once I have removed the index, solution upgrade worked just fine:

image

This does not seem to be  a problem for unmanaged solutions, but that’s expected since we can’t delete a field by importing an unmanaged solution. On the other hand, when importing unmanaged solutions, you may still change text field length for an existing field.. I did not try it, but I’m guessing Dynamics might not be able to publish those changes if the maximum size of all the columns  included into the index exceeds 900, since there is a limit on the SQL side.

Turns out business process flow entities have super powers

 

Did you know that, when setting up a workflow for a business process flow entity (Opportunity Sales Process, for example), we can configure that workflow to trigger on change of the related entities?

image

 

image

In the example above, we can trigger that workflow on change of the related opportunity entity fields etc. That’s an interesting feature which makes it possible to do this:

https://blogs.msdn.microsoft.com/crminthefield/2017/12/18/automate-business-process-flow-stages-using-workflows/#comment-48546

And which makes my older post on this topic pretty much outdated:

http://www.itaintboring.com/dynamics-crm/lets-rule-the-business-process-with-a-workflow/#comment-1361

The only caveat is that it has to be a background workflow since that functionality is not available for real-time workflow.

One thing I noticed when I tried it quickly is that there seem to be a bug – whenever I use “Select“ button to add more fields, I have to make sure I click “Save” and close the workflow designer window (or just “Save and Close”). Otherwise, if I click “Select” again to add more fields, all the selections I just made in the same designer “session” disappear:

image

And, then, click “OK”  and “Select” again:

image

But, if I click “Save and Close” first, then open the same workflow in the designer and click “Select”, everything looks good:

image