Monthly Archives: August 2017

Access Teams – why do we really need them?

What is the real difference between Access Teams and Owner Teams in Dynamics? Is it just that selection in the Team Type dropdown?

Maybe let’s start the other way around: what’s not different?

  • They are both represented by the same entity
  • We can add users to both types of teams
  • We can share records with both types of teams

So, if access and owner teams are that similar, why did Dynamics introduce Access teams at some point(there used to be Owner teams only in the past)?

This is where, if you have not read the following article yet, you probably should:

https://www.microsoft.com/en-us/download/details.aspx?id=45905

But I’ll try to provide a shorter version below.

The problem with the owner security is that there is a lot Dynamics has to look at to validate user’s permissions.

  • Every user will have security roles assigned to him/her directly
  • However, if a user has been added to a team, that user will inherit security roles from the team as well

Imagine what’s going to happen if there are 10 teams. Or, maybe, 100 teams. Or 1000.. Those security calculations can quickly become the one and only job Dynamics will be spending all server resources on.

There are two ways to make this situation better (other than to redesign the whole security model):

  • Create some sort of cache
  • Reduce the number of teams which have to be considered

And this is exactly what Dynamics is doing behind the scene. First of all, there is a security cache on the server. It’s calculated when the user logs in, and it stays there until it needs to be recalculated. There a few reasons why that kind of cache may have to be recalculated, but, essentially, it’s all about changing the set of security roles which the user has. For example:

  • A security role can be assigned to one of the teams where this user is a member
  • User’s membership in the teams can be updated

If that happens, security cache will be recalculated (and that will take a bit of time – you may notice a slowdown when navigating to another page in Dynamics at that moment). As far as security cache is concerned, that’s more or less how it works.

However, Dynamics is also reducing the number of teams that can affect that cache by introducing the Access Teams. Because, you see, you cannot assign security roles to the access teams. So there is no need to do anything with the security cache when such a team is created and the users are added to the team.

The way I see it, that’s the one and only reason why Access Teams were introduced in Dynamics. Otherwise, the system could just keep using Owner teams where it currently requires an access team. It becomes really critical when you start thinking about the team templates and “sharing” in general. For every team template, there can be one team per record in Dynamics. Imagine 10000 opportunities in the system, each having it’s own access team.. IF those were owner teams, it would be a very tough scenario for the security cache calculations. With the access teams, Dynamics can just ignore them when doing those calculations (yes, it still has to calculate access granted through sharing.. But, at least, it can safely assume those Access Teams won’t have any security roles).

So the difference is not, really, that we cannot assign security roles to the Access Teams.. or that we cannot use Owner Teams with the team templates.. those characteristics of the Access/Owner teams are there because of how these two types of teams are supposed to affect Dynamics performance. Owner Teams will affect the cache directly, so we should not be using them for sharing that much. Access teams can be completely ignored from the security cache calculations standpoint, so, if we want to use record sharing with teams, we should be using Access Teams for that.

 

 

New in V9: What’s that with Xrm.Page being deprecated?

Ever since Microsoft has published the “Important Changes Coming..” article that provides a very nice overview of what we should expect in the updated version of Dynamics, I could not stop wondering what does this mean:

With all the great reviews of this new release published on the web so far, I’ve never seen anyone asking a very basic question: so, what is going to happen to all the customizations which were supposed to be “supported” during the upgrades?

From the upgrade perspective, if you look at that screenshot above, you might think you just woke up to see your worst nightmare alive. Because if you have any client-side customizations at all, you’ll be most definitely using Xrm.Page.. which is now becoming deprecated.

So.. why don’t I speculate a little. And, if you have any specific details, please drop me a note, and I’ll update this post to reflect them.

1. What is a deprecated feature?

A deprecated feature is not, really, a feature that is immediately removed. More often than not, it’s a feature that’s not recommended for use anymore since it will be removed later. That’s my understanding, and, even though I can’t find a reference right now, I believe this is how Microsoft is treating “deprecated” features.

In other words, it seems we don’t need to worry about our javascript customizations stopping to work once V9 is here. On the other hand, we still have to start planning how are we going to deal with the removal of those deprecated features in the future.

2. What’s the story with the supported customizations vs unsupported customizations

From my standpoint, the difference between supported and unsupported customizations was, really, the corner stone in the foundation of all those business cases which we used to build in favor of using java script and / or plugins when we were talking to the clients.

If Xrm.Page is deprecated and meant for removal.. that’s going to be the last huge blow to that line of argumentation. There have been a few so far:

  • We had to recompile our C# code for new SDK assemblies when 365 came around
  • We had to switch from using ODATA / SOAP to using Web API on the client side (well, at least we had to start planning for the removal of the ODATA & SOAP endpoints)

In a way, that makes any javascript / plugin customization a potentially unsupported customization, so there is no certainty now. We are only working with the probabilities:

  • The probability of business rules stopping to work is, say, 5% (with the updated business rules designer, some features stopped to work, actually)
  • The probability of “supported” javascript stopping to work is, say, 10%
  • The probability of “supported” SDK stopping to work is, say, 10%
  • The probability of unsupported javascript stopping to work is, say, 30%

Etc.. See what I mean? It’s a shift of the paradigm – in terms of supported vs unsupported, nothing is certain anymore (and I mean nothing.. how about the whole Service Module being deprecated in v9? We could have guessed it would happen, eventualy, but still)

Another story has to be written now instead of that old one about supported vs unsupported – I’m not sure what the story is going to be.

But I got distracted..

3. What does Xrm.Page mean on that screenshot above?

That’s what I am really not sure about. It seems that the majority of those changes are focused on the “context”. Which is understandable – if you are in the context of the form, you have access to the form attributes. If you are in the context of the editable grid, you should have access to the grid attributes. However, how do you access form context from the ribbon button if there is no Xrm.Page? If there is an alternative global object that will allow that kind of access, then why not to keep Xrm.Page.. Besides, there are methods from the Xrm.Page namespace which are mentioned on the right side in that table (in other words, in the “replacement API” column):

In other words, it seems that, even though Xrm.Page is deprecated, some of the functionality is supposed to stay there.

I guess we’ll see what’s going to happen really soone, once V9 is here. But, like I said, if you have any more details for now, I’d really appreciate if you could drop me a note so I could share those details here.

CodeNow: creating a plugin for Dynamics in XrmToolBox

First of all, why would you need to build a plugin in the XrmToolBox? Isn’t it what the Visual Studio is for?

I think the answer is “yes and no”. See, if you are a developer and have all the tools.. you probably don’t need to read this post (other than out of curiosity). But, if you are a Dynamics administrator, or, maybe, you are a developer who just needs to create a plugin quickly while you are away from your work computer.. Whatever the reason is, if you do need to create a plugin for Dynamics, and if you don’t have Visual Studio installed, you can do it with the CodeNow plugin easily now.

Before you continue, you may want to get CodeNow plugin installed, so here is where you’ll find the instructions:

http://www.itaintboring.com/tcs-tools/code-now-plugin-for-xrmtoolbox/

Once you have it installed, the process looks like this:

  • Using XrmToolBox, you can build a plugin
  • And, then, you can use PluginRegistrationTool to register the plugin

For the plugin registration tool, you will find a detailed walkthrough here:

https://msdn.microsoft.com/en-us/library/gg309580.aspx

In this post, I’ll walk you through the steps required to compile a plugin in XrmToolBox.

Here we go:

1. Open XrmToolBox and load CodeNow plugin

2. Select “Plugin” checkbox

Once you have selected the checkbox, CodeNow will display sample plugin code. You can actually use “Compile” command to compile plugin dll at this point, but it won’t, really, be very functional yet.

However, that sample code has all the basic code you need to start with..

So, why don’t we create a plugin for the account entity that will ensure that nobody will set account name to “Test”

3. Here is the code we are going to add

  if(entity.Contains("name") && (string)entity["name"] == "Test")
                 throw new InvalidPluginExecutionException("Cannot use 'Test' for the account name");

   

4. It’s time to compile the plugin?

When you click “Compile”, the tool will ask you for the dll file name, so.. just choose the file name you want. “Test.dll” might be just fine:

5. Now you can use the PluginRegistrationTool to register the plugin

And the SDK step, of course:

6. And, now, let’s do a quick test. Let’s try to update the account’s name:

Worked out just as we planned!

 

Code Now plugin for XrmToolBox

Code Now plugin for XrmToolBox

Strictly speaking, it’s not part of TCS Tools. But, either way.. it’s kind of cool to be able to run C# code directly from XrmToolBox, especially when you need to do something quickly. You can do it with the Code Now plugin right now:

To install the plugin, just download it from the XrmToolBox plugin store

DISCLAIMER: You can use TCS Tools and Code Now plugin on your Dynamics projects – there are no strings attached. However, if you do so, that means you agree that the author (me) cannot be held responsible for any issues that may or may not occur in your environment due to the use of these tools.
If you there is an issue with the CodeNow plugin you wanted to get fixed, or if you have a suggestion to implement, drop me a message:

How to turn this poor one-liner into a nice multi-line notification?

If you happened to use Xrm.Page.ui.setFormNotification in your javascript customizations, you have probably noticed that it does not support line breaks. Try adding <BR/> tags into those notifications, and you’ll get something ugly.. like this:

Apparently, setFormNotification does not really respect all those html tags – instead, it just displays them as regular text.

So, how do we make it more like this:

Or, maybe, even like this:

It’s possible, but only if we start messing with HTML in those forms. Which, of course, is far not the best practice. However, even though it may not be the best practice, it may still save you quite a lot of time if it were a choice between implementing your own notification engine as compared to just implementing a quick unsupported customization in javascript on top of the out of the box notification functionality. That said.. Let’s see how you can turn those out of the box one-liners into the nice multi-line notifications.

You can always use F12 in google Chrome to see exactly what it’s all about; however, I’ll just save you some time and summarize the problem:

when Dynamics is displaying those notificaitons, it’s displaying them in the <span> HTML elements. However, while innerText has all the right HTML, innerHTML property has the same HTML in the escaped form. So, for example, it’s using &gt, &lt in place of > and <)

Really all we need to do is this:

span.innerHTML = span.innerText;

We just need to find those span elements, and we need to run that code at the right moment.

Here is a function which will reset innerHTML – technically, you can add this function to a web resource, attach that web resource to your form, and, then, keep calling it after every call to setFormNotificaiton or clearNotification.

ResetNotificationInnerHTML: function () {
        debugger;
        var notificationsElement = parent.document.getElementById('crmNotifications');
        if (typeof notificationsElement != 'undefined' && notificationsElement != null) {
            var notificationSpans = notificationsElement.getElementsByTagName('span');
            for (var i = 0; i < notificationSpans.length; i++) {
                var span = notificationSpans[i];
                if (span.innerText != span.innerHTML) {
                    span.innerHTML = span.innerText;
                }
            }
        }
    }

We can take it a bit further, though. Can we make it work in such a way that any call to the Xrm.Page.ui.setFormNotification (or clearNotification) would automatically call ResetNotificationInnerHTML, too?

That’s where we can update the Xrm itself.


UpdateXrm: function () {

        Xrm.Page.ui.constructor.prototype.originalSetFormNotification = Xrm.Page.ui.constructor.prototype.setFormNotification;
        Xrm.Page.ui.constructor.prototype.originalClearFormNotification = Xrm.Page.ui.constructor.prototype.clearFormNotification;

        Xrm.Page.ui.constructor.prototype.setFormNotification = function (message, level, uniqueId) {
            this.originalSetFormNotification(message, level, uniqueId);
            ResetNotificationInnerHTML();
        };

        Xrm.Page.ui.constructor.prototype.clearFormNotification = function (uniqueId) {
            this.originalClearFormNotificationuniqueId(uniqueId);
            ResetNotificationInnerHTML();
        };

        ResetNotificationInnerHTML();

    }

That function above will add originalSetFormNotification and originalClearFormNotification to the Xrm.Page.ui, and it will store original setFormNotification and clearFormNotification in those two new methods.

Then it will replace those original setFormNotificaiton and clearFormNotification methods in such a way that they will now be calling ResetNoficiationInnerHTML, too.

So, now, you can simply call UpdateXrm() somewhere in the onLoad of your form.. and, then, you can keep using Xrm.Page.ui.setFormNotification as usual. Except that you will be able to use html tags in your notifications now.

I have added these scripts to the same javascript library that you can use to configure tabs, sections, and fields on the forms – have a look at this post for the details

If you wanted to try that library, make sure you have deployed updated version of the TCS Tools solution

Then, add tcs_/scripts/FormSupport.js web resource to your form. Once it’s there, you can simply add the following onLoad event handler:

TCS.FormSupport.UpdateXrm

It’s the same UpdateXrm function that I talked about a bit earlier in this post.. it’s just part of the library now.

That’s it – you should be able to create multi-line notifications. And, if you are feeling a little adventurous, you can actually add other HTML tags to the notifications. For example, how about adding a link:

Xrm.Page.ui.setFormNotification(“<a href=’http://itaintboring.com’ target=’_blank’>It Ain’t Boring</a>”, “INFO”, “3”);

 

Have fun!

Code Now: run the code, build a plugin, or create a utility.. directly in #XrmToolBox

Just fresh from development, a few more tools have been added to the Code Now plugin for XrmToolBox:

  • Code Now can build an exe-file
  • Code Now can build a plugin
  • You can save your code to a file and/or load it from a file

And, because it’s CodeNow, you can do it right NOW, without even having to deploy a Visual Studio.

If you are wondering what that plugin is, you may want to read this post first:

Run C# code into Dynamics NOW!

Eventually, you should be able to download the plugin directly from the plugin store, but, for the time being, you need to download it from this site (make sure to read the post above – all those details are there)

So, how does it work with the executables/plugins?

It’s all done using the compile command. Whether the plugin will build an exe-file or a dll (for a plugin) depends on whether you have selected that “Plugin” checkbox:

Creating an exe-file

When building an exe file, the tool will take your CodeNow function and “using” directives, it will add some extra code required for the executable to compile, and it will build an “exe” file after that.

You will need to:

  • Name the file when the tool asks you for it
  • And click OK

Once the file is ready, and that should take just a few seconds, you’ll see that file and a few additional dll files in the folder:

In the example above, I just created that “getaccounts.exe” file.

What you still need to do after that manually(for now), you need to open getaccounts.exe.config file (if you name the file differently, this configuration file will also be named differently), and you need to configure the connection string.

Here is how it will look like when you open it:

What you see on the screenshot are a few sample connection strings which you can use to define your own connection. Just make sure to keep the same connection name (CodeNow).

If you wanted to see more examples, the msdn page below would definitely help:

https://msdn.microsoft.com/en-us/library/mt608573.aspx

Have a look at the screenshot below – I just added the connection string for my online Dynamics 365 trial instance:

And, of course, once you have configured the connection, save the file.

What you just did with the connection string only needs to be done once. Next time you compile that exe file, the configuration file will not be replaced, so, if it’s the second time you are compiling the file.. you could have skipped all those configuration steps and start your utility right away.

Remember there was that “LogMessage” method available to you when you were using “Run Code” option? Once you have an exe, LogMessage will still work, but it will be redirecting all output to the console. Here is what you are going to see then:

And that’s it. If you want, you can keep running your new utility manually. Or you can choose to schedule it.. Maybe there is something you need to do in Dynamics every morning at 6AM? Not a problem – build a utility, schedule it with Windows Task Scheduler, and don’t bother wakeing up that early anymore.

But, there is another option, too – you can also build a Dynamics plugin using CodeNow. I will explain how that works in a separate post, but, if you want, you can try it right NOW:) Or wait until tomorrow..

Build a plugin for Dynamics using CodeNow

How required are required fields in Dynamics?

As the saying goes “you are not allowed, but if you really want to.. you can”

When I’m thinking of the required fields, this is exactly what comes to mind. They are not supposed to be empty according to the manuals:

But, if you really want to, you can usually find a way. Everyone who worked with Dynamics for a little while has, probably, been able to discover this amusing feature of the required fields, but, if you have not done it yet, I’ll explain one scenario (and there are others for sure).

You see, that whole thing about being a required field only applies when you are looking at the form and that field is highlighted as required:

It works just fine there, so, let’s say I have entered some data and saved the record:

Nothing stops me from defining a workflow that will clear that field:

I can run that workflow on the record I just saved without any problem:

And, once I click “F5” to refresh the screen, I see a perfectly empty required field:

Why am I blogging about it? It’s simply to emphasize a few things which new Dynamics developers/admins will usually realize once there is, already, a data consistency problem:

  • You can make a field required, but it’s all about client-side validation. On the database level, Dynamics would not mind at all if that field were left empty
  • There are at least a few ways you can push an empty value into a required field: you can use a business rule to temporarily make that field optional; you can use javascript for the same purpose; you can use a workflow, a plugin, or a javascript Web API call to simply bypass that validation; and you can use some integration software to do the same (SSIS, Scribe, etc)

If you do want to enforce that requirement on the server side, you have two options:

  • Create a synchronous plugin and register it on the create and update – check for the value in the required field (you might use a post image for that), and throw an error if there is no value
  • Create a real-time workflow and stop it as cancelled if that required field has no value

That way, you will actually be able to guarantee that there will be no records where that particular field is empty. Otherwise, if you look at it from the data consistency perspective.. It’s simply the Murphy’s law that things will go wrong in any given situation, if you give them a chance.

When does your week start?

There is a minor(and rather hidden) setting in Dynamics that we can easily overlook, but, every now and then, it can be the sole reason for some interesting discrepancies in the reporting/search functionality.

Before we go there, here is what google had to say:

1. We normally think of the weekEND as of Saturday/Sunday(it’s the same in Canada/US):

2. For the majority of the world, the first day of the week falls on Monday (but it’s different for Canada/US/Japan):

Now, how did it happen that the week ENDs on Sunday and starts on Sunday in Canada/US is beyond me, and it could be just one of those funny little nuisances if not for the reports and advanced find in Dynamics

For example, if you defined a filter this way:

What would you actually see once you have clicked the “Results” button if it were Monday today? Would there be accounts modified “yesterday” (which would be Sunday)?

The answer depends on when the week starts. If it starts on Sunday, then you would not see the accounts modified “yesterday”.. although, you would see some other accounts – those modified the previous Sunday. Which might be somewhat different from what you really wanted to see.

This kind of weekly conditions (this week, next week, last week, etc) work the same way in the Advanced Find, in the fetch-based SSRS reports, in the saved and/or system views.

There are two ways to deal with this:

1. Be mindful of this functionality and use those weekly filters with caution

2. If this is still bothering you, re-configuring the First Day of Week in Dynamics  might help – you can do it from the Administration->System Settings->Formats->Customize->First Day of Week. Just keep in mind this will affect all users: