Problem
I was asked to look at a Sitecore solution, where it was not possible to show a custom application in the sitecore client. In fact it was not possible to show a number of the standard dialog’s, for example the presentations dialog (see the image above).
It was strange as some dialog’s worked and others did not, so I opened the developer tools which immediately showed me what the issue was.
As you can see a lot of stuff is missing? This is because Sitecore’s HTTP handler is looking for URL’s that begin with “WebResource.axd” and it is case sensitive.
Rewrite Rules Strike Again
To improve SEO, the following rewrite rule was introduced in the web.config to lower case ALL url’s
Now whilst this was great for the websites SEO; it was responsible for breaking the sitecore client as there are a number of URL’s which are case sensitive.
Solution
The solution was to identify all the case sensitive sitecore client URL’s and exclude them from the lowercase rule.
Now instead of trying to write the most complex regular expression ever, which would catch all the website URL’s and avoid all the Sitecore client calls.
I decided to add an individual condition match pattern for each (URL) and then used the negate=true to exclude the URL from the redirect rule.
Thanks to Marc Downer for following version which fixes issues relating to the path and query strings being stripped, from the URL.
<rewrite> <rules> <!-- https://blog.coates.dk/2018/01/15/lower-casing-rewrite-rules-breaks-the-sitecore-client/ --> <!-- Take redirectType="Temporary" out of production --> <rule name="LowerCaseRule - not including querystring" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{PATH_INFO}" pattern=".*[A-Z]" ignoreCase="false" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" /> <add input="{REQUEST_URI}" pattern="^/(sitecore)" negate="true" /> <add input="{REQUEST_URI}" pattern="^/(sitecore modules)" negate="true" /> <add input="{REQUEST_URI}" pattern="^/-/" negate="true" /> <add input="{REQUEST_URI}" pattern=".*(-/media).*" negate="true" /> <add input="{REQUEST_URI}" pattern=".*(~/media).*" negate="true" /> <add input="{REQUEST_URI}" pattern=".*(~/icon).*" negate="true" /> <add input="{REQUEST_URI}" pattern="WebResource.axd" negate="true" /> <add input="{REQUEST_URI}" pattern="ScriptResource.axd" negate="true" /> <add input="{REQUEST_URI}" pattern="jsnlog.logger" negate="true" /> <add input="{REQUEST_URI}" pattern="Telerik.Web.UI.WebResource.axd" negate="true" /> <add input="{REQUEST_METHOD}" matchType="Pattern" pattern="POST" ignoreCase="true" negate="true" /> </conditions> <action type="Redirect" url="/{ToLower:{R:1}}" appendQueryString="true" redirectType="Temporary" /> </rule> </rules> </rewrite>
Ignore POST requests
Thanks to Søren Kruse for pointing this out; The redirect will change a POST requests to a GET and you will lose any data in the body of the original request. Therefore you should ensure that POST requests are not redirected.
<add input="{REQUEST_METHOD}" matchType="Pattern" pattern="POST" ignoreCase="true" negate="true" /><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>
Well I hope this helps, Alan
There’s a few things wrong with this. It strips the path from the url and just redirects to the domain. It strips query strings. Here is my corrected version; note the changes for match url, the first condition input, and action url. It ignores query string case and just appends the query string.
I’d like to correct that intro to “There’s a few things that were wrong for me, perhaps this can help others.”
Also thanks Alan Coates for the exception set. Those are tough to build.
No worries thanks for the feedback
Where is the corrected version?
Here’s the version we’ve been using:
It’s stripping the rule from the comment. I’ll see if I can figure out how to get it to not strip it.
match url=”(.*)”
start conditions
conditions>
add input=”{PATH_INFO}” pattern=”.*[A-Z]” ignoreCase=”false”
add input=”{REQUEST_FILENAME}” matchType=”IsFile” negate=”true”
add input=”{REQUEST_URI}” pattern=”^/(api)” negate=”true”
add input=”{REQUEST_URI}” pattern=”^/(sitecore)” negate=”true”
add input=”{REQUEST_URI}” pattern=”^/(sitecore modules)” negate=”true”
add input=”{REQUEST_URI}” pattern=”^/-/” negate=”true”
add input=”{REQUEST_URI}” pattern=”.*(-/media).*” negate=”true”
add input=”{REQUEST_URI}” pattern=”.*(~/media).*” negate=”true”
add input=”{REQUEST_URI}” pattern=”.*(~/icon).*” negate=”true”
add input=”{REQUEST_URI}” pattern=”WebResource.axd” negate=”true”
add input=”{REQUEST_URI}” pattern=”ScriptResource.axd” negate=”true”
add input=”{REQUEST_URI}” pattern=”jsnlog.logger” negate=”true”
add input=”{REQUEST_URI}” pattern=”Telerik.Web.UI.WebResource.axd” negate=”true”
add input=”{REQUEST_METHOD}” matchType=”Pattern” pattern=”POST” ignoreCase=”true” negate=”true”
end conditions
action type=”Redirect” url=”/{ToLower:{R:1}}” appendQueryString=”true” redirectType=”Temporary”
Maybe a code site link? https://controlc.com/7c6c8678
Hi do you have twitter, linkedin,etc. account that I can link to for credit for the fix?
I supposed linked in is easiest – https://www.linkedin.com/in/marc-downer-71962194 Thanks!
‘thanks for the solution and feedback 🙂 I was a bit quick and just wanted to get rid of the errors in the sitecore client 🙂
There were a lot of issues with this solution 🙂
Where is your corrected version?
I have corrected the redirect rules not for the post 🙂
Thanks Alan – This was helpful – I had to add following line as well:
Pingback: SXA Lower case URL | Sitecore basics!