Tip #1063: Do not touch currency system views

This tip comes from Guillaume Domont. (And you can get your names into the Dynamics 365 History Book™ too by sending your tip to jar@crmtipoftheday.com.

Guest Microphone

I found a quite interesting bug in my last project.

As the CRM/Dynamics 365 is used worldwide, we had to handle the currency changes. The standard currency lookup view looks like this:

OOTB Currency Lookup View

The project architect in his clever thoughts designed this view to be more performant, i.e. remove every columns and just let the currency name:

Customized Currency Lookup View

We modified the currency lookup view and handed it over to the testers. After a few months, the testers came back to us and said: “Did you notice that the currency symbol is not updated?” (when you select a different currency – t.j)

Change currency breaks the symbol

So after a few weeks of the Premier Field Engineering support looking for the problem without any luck, I discovered that the OOTB currency lookup view has the currency symbol in it and that somehow Dynamics 365 is doing some magic tricks to collect that symbol and set the collected symbol in front of every money field on the form.

Lessons learned: never modify the currency lookup view 🙂

Tîpp Jäår

I lied virtualized the reality: Dynamics 365 History Book™ does not (yet?) exist. But you can check the work in progress and leave your comments on a very much real Dynamics 365 Book!

Tip #1062: When recompile is not enough

As was mentioned in the Tip 1058, the most simple and easy way to deal with TLS 1.2 in your code is to recompile it with .net 4.6.2+.

As David “Xrm.Tools” Yack discovered, it may not work for some of the existing projects. The issue is that, when the framework version changes in Visual Studio there is a secondary setting in web.config that can override that!

<compilation debug="true" targetFramework="4.7" />
<httpRuntime targetFramework="4.5.2" />

The httpRuntime target framework stays the same when you change the project settings – it has to be manually updated. If you don’t, then the project will really be running as 4.5.2 while deployed as 4.7. If your project tries to connect to Dynamics 365 version 9 (where TLS 1.2 is enforced), you will receive seemingly unrelated errors, and/or unexpected results from some function calls.

It’s the small things that bite you hard! – David Yack (c) 2018

Tip #1061: Hierarchical security rebuild

Dynamics CRM TipperWe have not done a mini truckstop for a while so it’s good to bag one at the beginning of the year.

Question

It’s a first time for Greg “Stealth MVP” Olsen to ask the MVP crowd a question.

We have Hierarchy Security setup and working well for an enterprise customer, but not sure how long it takes to apply once we have saved the settings. During our testing it doesn’t look like it’s in real time or immediate.

Can someone inform me on what it does in the background technically and how long I should expect to apply?

There is a good article available, but it doesn’t inform the reader if its instant or takes X minutes/hours etc or what it is doing behind the scenes to set up the security technically.

Answer

Adam “First!” Vero does not have his truckstop nickname for nothing, leaving others no chance to answer.

A table called SystemUserManagerMap is built to store who reports to whom and at what level. Eg it will contain a row for Charlie (as the user) and Bob (his boss as “manager”) at level 1, and a second row for Charlie (the user) and Alice (Bob’s boss) at level 2, and a row for Bob > Alice at level 1.

By pre-building this table it should make actual queries much faster (than some horrible iterative query) especially for retrieve multiple – join from current user through this SystemUserManagerMap table (filtered by depth set in configuration) to the entity table to find all records owned by users somewhere in my reporting chain. (In reality it goes SystemUserManagerMap then SystemUserPrincipal table to find all records owned by users who report to you, plus owned by any teams they are in. Likewise through those to the POA table to find records visible to your reporting chain via shares).

If for some reason that table is not built, fails, takes too long etc then queries won’t work properly. From memory, the table is built to represent all depths of reporting (via manager or position depending on settings). Then if you change depth from say 3 to 5, the records already exist and the table is not rebuilt. The table is modified if you change a user’s manager/position (depending on which is in use). Changing from manager to position approach would cause a complete rebuild, as far as I can tell.

Microsoft Scalable Security whitepaper covers more detail: https://www.microsoft.com/en-us/download/details.aspx?id=45905

Tîpp Jäår

The download, even though slightly out of date, contains other useful whitepapers – make sure to study them after closing this window.

Tip #1060: Quickly create vector/SVG images for Dynamics 365

We have had several tips about icons in Dynamics 365. As Tanguy reminds us, if you want your icon to show in the unified interface sitemap, you need to use Scalable Vector Graphics (SVG) format.

Andrew Magnotta from Microsoft shares a tip about how he quickly creates SVG images for Dynamics 365.

Method Draw – Browser based .svg editor

The support for Scalable Vector Graphic (SVG) web-resources have been introduced in D365v9 and it looks like they’re here to stay as the new default for adding custom images (logos/icons) to your D365 instance. However, support for creating custom .svg images can be tricky with the everyday image editors you maybe accustomed to (ex. Paint.NET). I did a quick search and found a nice + free browser based vector creating site called Method Draw (http://editor.method.ac/). This site allows me to import a custom logo image from an standard format (jpg, png, etc.), quickly turn it into an SVG, and save it locally to import into D365:

 

  1. Set Canvas size – Depending on the intended use of the image (up to 400x50px for Theme logos or the standard 16×16 / 32×32 for entity icons).

2.       Set Background – Can be transparent or any HEX color

  1. Import Logo Icon (jpeg, png, etc…)

  1. Drag to Resize Image (auto adjusts size… which is nice!)

  1. Save file and import into D365 as .svg web resource

  1. Add to Theme and Publish

  1. Renders nicely in both Classic and UUI interfaces

Classic:

Unified Interface:

Tip #1059: Enabling Tracking and Rating for Portal Pages

Two common requests for portal pages is enabling tracking (seeing who has gone to a page) as well as ratings for pages i.e. the ability to say if a page was useful or not. Rating can be found relatively easily under the options for a web page (log in to the portal as an Administrator, edit the page and go to options. However tracking a page (logging when a page is loaded on someone’s browser) is not as obvious.

My rule of thumb for the portal is, if in doubt, go to the record in Dynamics 365. The configuration record for a web page/entity form/web form should contain all of the possible settings (where else would they be?). Sure enough, if we browse to a web page record, we see the ability to enable these under the page options.

Rating puts a five-star rating on the page. This is most commonly used for knowledge article pages but, in principle it can be enabled anywhere on your site.

Tracking automatically adds a record to the Web Page Log entity every time an enabled page is visited. The IP address of the visitor is captured and, if they have logged onto the portal, it will also link the Web Page Log record to their Contact record.

Finally, for those looking for a bit more in-depth analysis, in the Content Snippet records, there is a Tracking Code snippet where you can add a tracking code e.g. Google Analytics and monitor your site that way.

Tip #1058: Connect to version 9 in your code

This tip is courtesy of Matt “SDK Deity” Barbour to make sure that we (developers) can stay connected to our beloved instances regardless of the version. Before copying the write-up almost verbatim, short version:

tl;dr

TLS 1.2 is now enforced so, for seamless connections to your version 9 instances, use the latest SDK tools and rebuild your projects with .NET 4.6.2+.

Matt has the mic

(Matt works at Microsoft so from this point forward “I” == Matt and “we” == Dynamics 365 team)

This is a bit long and detailed, however I believe it will be worth the read if your building for, or supporting folks that are building for, the crm\xrm platform.

With the release of the v9 platform we are now enforcing the use of the TLS ( Transport Layer Security) 1.2 + Only.

We made notice of this here and here.

Its important to note that TLS 1.2 is not a ‘new’ thing. We have been supporting TLS 1.0, 1.1 and 1.2 since v7 of the platform, the change we are making in v9 is that we will drop support for TLS 1.0 and 1.1, requiring all connections to connect to us using TLS 1.2 + only. Why we are enforcing this is covered in the blog with external links and such, so I encourage you to dig though that. The short of it is: its to improve security.

Now the rub 🙂

Our tools and platforms though v8 have been based on .net 4.5.2, which defaults to TLS 1.0 for security. What this means is that CRM and Dynamics Tools shipped up though v8 will not seamlessly connect to v9. When this shows up it always manifests as an auth failure. Looking at the logs, you will see a message that looks like this:

In 8.1 connectors :

Microsoft.Xrm.Tooling.CrmConnectControl Information: 8 : Login Status in Connect is = Validating connection to Microsoft Dynamics CRM...
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : ERROR REQUESTING Token FROM THE Authentication context
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : Source : mscorlib
Method : ThrowIfExceptional
Date : 1/19/2018
Time : 10:23:27 AM
Error : One or more errors occurred.
Stack Trace : at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.ExecuteAuthenticateServiceProcess(Uri serviceUrl, ClientCredentials clientCredentials, UserIdentifier user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean isOnPrem, String authority, Uri& targetServiceUrl, AuthenticationContext& authContext, String& resource)
======================================================================================================================
Inner Exception Level 1 :
Source : Microsoft.IdentityModel.Clients.ActiveDirectory
Method : Close
Date : 1/19/2018
Time : 10:23:27 AM
Error : Object reference not set to an instance of an object.
Stack Trace : at Microsoft.IdentityModel.Clients.ActiveDirectory.HttpWebResponseWrapper.Close()
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationParameters.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationParameters.d__8.MoveNext()
======================================================================================================================

In the bits on nuget now the error looks like this:

Inner Exception Level 1 :
Source : System
Method : GetResponse
Date : 1/16/2018
Time : 4:37:46 PM
Error : The underlying connection was closed: An unexpected error occurred on a send.
Stack Trace : at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Description.MetadataExchangeClient.MetadataLocationRetriever.DownloadMetadata(TimeoutHelper timeoutHelper)
at System.ServiceModel.Description.MetadataExchangeClient.MetadataRetriever.Retrieve(TimeoutHelper timeoutHelper)
======================================================================================================================
Inner Exception Level 2 :
Source : System
Method : Read
Date : 1/16/2018
Time : 4:37:46 PM
Error : Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Stack Trace : at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
======================================================================================================================
Inner Exception Level 3 :

Errors like this, in conjunction with trying to connect to a new trial or a v9 instance is a dead giveaway that it’s a TLS Problem.

How to deal with this

There are a few ways to deal with this,

For tools we ( Microsoft ) provide

the most simple and easy way to deal with it is to use the current SDK tools.. Now, in our effort to help keep folks up to date, we have made getting the SDK tools a bit more complicated but we did it for good reasons. Historically, we would post a point in time copy of all the tools and samples into a massive download, the problem is that to get all that together, it required a number of teams to work together to put a package together to post, this slowed down pushing updates. Most folks have noticed that we do not have the 9.x SDK posted that way. If you have not noticed yet … We are not using a Single download anymore 🙂

We have moved over to Nuget to provide the current SDK bits. This allows us to quickly patch and update SDK assemblies and tools.
We talked about this here. To help with the SDK Download and to keep you current, Jim Daly wrote up a handy powershell script in the documentation to help you get and keep current the SDK, its one link off the central dev page bug for reference its here. Using that script will always keep you current going forward with tools.

For Code built with our SDK

The most simple and easy way to deal with this is to recompile your code with .net 4.6.2+. if your code is already compiled with .net 4.6.2+ then your good to go. EXCEPT if you started with VS and a project that started with .4.5.2 :). There is a quirk in VS which causes it to run in 4.5.2 mode even after you have changed the build version. The simple way to deal with this is to clean your project after you change the .net version , close VS and delete the bin directory ( You need to get rid of the .vhost. files ) then restart VS and reload your project. That should kick it into using the .net 4.6.+ runtime. *note: this does not impact the binaries, only on the debug experience in VS.

For existing code that cannot be recompiled

We cover a registry setting in the blog articles that can be applied that will force .net to use TLS 1.2, I want to stress caution with this though as this is very much the sledgehammer approach as it forces all .net software on the machine to use TLS 1.2 +.

For non .net software

Check with your vendor on how to enabled TLS, for most languages it can be done with a simple config entry

One important note for .net based apps

Its really attractive to use the command: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; I cannot discourage you from using this enough… this forces the TLS 1.2 protocol all the time. While this seems great, if you ship software that lives more than a year or so, when the next security protocol appears and is adopted by the industry, your application with be at risk.

For Powershell

With regard to PowerShell scripts however, You will need to add [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 to your Powershell Script BEFORE you call Get-CrmConnection.

Tîpp Jäår

Wow, that’s one comprehensive write up, not much to add. You’ve been warned, folks!

(Our cover image – the one you see on facebook or twitter – is by Igor Ovsyannykov on Unsplash)

Tip #1057: Voice of the Customer says “Don’t change your URL”

Jerry Weinstock found out the hard way that if you change your Dynamics 365 instance URL after you install Voice of the Customer, survey responses will not synchronize with Dynamics 365. Survey responses will still be captured in Azure, but they will not appear in Dynamics 365.

  • If you want to change your URL, do it before you install Voice of the Customer
  • If you have already installed Voice of the Customer, contact Dynamics 365 support.

Tip #1056: Immersive Excel: Should I stay or should I go?

When you export to Excel Online in Dynamics 365 online, you can edit values and create new records, then click the “Save changes to Dynamics 365” button, the changes will be uploaded to Dynamics 365.

Sometimes when you hit the save changes button, you may be presented with this option:

So should you stay or leave? This is confusing, because the message reads as if the data will be lost if you hit “leave page.”

If you click “leave page,” it will look like your changes are saved to Dynamics 365, but the import file created will be empty and the changes will not be saved to Dynamics 365.

If you click “stay on page, nothing will happen, but if you click the “save changes” button again, the changes will upload to Dynamics 365.

 

Tip #1055: Dynamics 365 Service Administrators and security groups

In Tip 844 we talked about the Dynamics 365 service admin role in Office 365, which allows people who aren’t Office 365 global administrators to manage Dynamics instances, copy sandboxes, and other administrator features.

So if you give someone the Service Admin role and they don’t see the ability to do something like copy an environment, one thing to check is the security group associated with the instance.

 

  1. In Office 365 Admin Console, go to Settings>Services & Add-ins>Dynamics 365>Manage your Dynamics 365 Settings
  2. Select the instance and click “Edit”
  3. Verify if there is a security group selected in the “Security Group” field for the instance.

If there is a security group selected for the instance, the Dynamics 365 Service Administrator must be a member of the group to manage the instance.

Tip #1054: Hiding Field Service fields

Today’s tip is from Scott LeFante. Scott is the co-host of the “At Your Service” podcast, heard on the CRM Audio podcast network.

When working with Work Orders and their corresponding data, such as Service Tasks, be careful about removing or hiding fields from forms.  Field Service functionality includes many out of the box plug-ins and workflows that fire when certain actions are taken or certain values are entered on the various forms and entities.  There are many examples of when and where this occurs, some are simplistic to understand and determine while others may make you scratch your head to determine what the issue may be and how to resolve it.

For example, let’s say you hide Sales Tax Code, because you won’t be calculating tax in CRM, from the Work Order Form, but you set the Taxable field on the Work Order Type to Yes.

If you use that Work Order Type on the Work Order, you will not be able to save the work order record.

This is a simplistic example, but one that is important to understand as there are many examples of this from Work Orders to Bookable Resource Bookings, Work Order Products, Work Order Services, etc.

I recommend the following best practices when dealing with Field Service forms and functionality:

1) Make copies of all forms you plan to alter and use those forms for your users.

2) Understand the In’s and Outs of all forms and functionality you are implementing.

3) If you do not require certain fields within forms within the Field Service area, and they aren’t required fields (either conditional or non-conditional), think about putting them in a separate tab and hiding the tab/fields.

Photo by Don Agnello on Unsplash