Xrm.Navigation.openForm (openForm documentation) allows you to pass parameters to the form being opened in the formParameters parameter. Under the covers these formParameters are then sent on the query string to the form page. If you use the name of an existing attribute on the form you are opening it will map the value straight through to field on the page when it opens.
However (at least in version 9.0) when using the old Classic UI the parameters are not cleansed for the URL that this will create. So if there is text in any of your parameters and it contains characters that are invalid for the URL (typically things like < and >) then the call will fail with something like:Parameter name: Expected 'SafeString' data type for 'new_clientname' parameter in 'Request.QueryString'.
in the error text produced.
So how do you protect against this … the Xrm JavaScript library provides two Xrm.Encoding methods that could help Xrm.Encoding.htmlAttributeEncode and Xrm.Encoding.htmlEncode as normal these are poorly documented but it seems the main difference is htmlEncode is a faster quick encode that only encodes certain characters. Microsoft’s own documentation about sending parameters to forms suggest using the JavaScript encodeURIComponent method – sadly while this allows the call to work the strings don’t get decoded before they are displayed on the receiving form – so something like this:
formParameters["new_clientname"] = encodeURIComponent("Fred Bloggs <Test>");
Then it shows up on the form like:
Pretty definitely NOT what you wanted. So do the Xrm encoding methods fare any better? Well differently is the answer htmlAttributeEncode :
And htmlEncode was similar but left the spaces alone:
So it seems none of these encoding styles is picked up when the form is populated. So how can we get the data decoded? Forms allow you to specify custom query string parameters … perhaps these will work – trying:
maybe that will be enough to force to decode from SafeString on access. Sadly it made no difference at all. So we are back to JavaScript – the actual use case was pre-setting some fields on the create of an item. So we will encode and then we need to decode on the create – so in the OnLoad of the form we need to do something like:
var clientNameAttribute = formContext.getAttribute("new_clientname");
clientNameAttribute.setValue(Xrm.Encoding.htmlDecode(clientNameAttribute.getValue()));
And finally we get what we need:
So much for low code/no code customisations! Obviously the more information you are trying to pass through to the form the worse this gets – and this is all in the URL too so is not really appropriate for large amounts of data. So in a later post I will show you how to pass things using localStorage or sessionStorage in a more generic and extensible way.