Introduction
After typical back a forward between myself and my product manager where he was convinced I'd introduced a bug and I was convinced he was an idiot. I eventually discovered that neither was the case.
My product manager had decided to stop using Safari on his iPad and instead switch over to the Google search app. This was the cause of the raging disagreement.
And this is why...
Background
Asp.Net can, in theory, work in a limited capacity, without javascript. The Asp.Net engine automatically looks at the user agent supplied with the HTTP request header and uses this to make an assumption about what the browser can and can't do.
You can explore the result of the Asp.Net engines identification and assumptions using the Request.Browser
property of the current HttpContext.
Firstly I didn't realise that Asp.Net was doing this at all. Then I had no clue as to how it done either.
Then I discovered the following folder:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Browsers
This folder contains a number of files which describes pattern matches which it compares against the user agent. When it finds a match it selects that browser and logs those capabilities so components designed to cope can change their behaviour to conform with that browser.
When using Chrome and Google Search on the iPad, the ASP.Net engine reported the browser as a "Generic Mozilla" browser. This switched off javascript within ASP.Net and broke my application.
Fixing the Problem
You can override the browser type by adding your own browser files to your application.
Create a folder in the root of your application called App_Browsers
and add a file with any file name but with the .browser
file extension.
Specifically for Chrome on iOS and Google Search I resolved the problem by adding the following XML to the file:
The parentID describes which existing browser schema you're inheriting from. The userAgent match is the text to match for this schema. The capabilities are then overridden with those specified.
Adding this file re-enabled Asp.Net's use of javascript and fixed my application in these browsers.
<browsers>
<browser id="CriOS" parentID="Safari">
<identification>
<userAgent match="CriOS" />
</identification>
<capabilities>
<capability name="browser" value="CriOS" />
<capability name="layoutEngine" value="WebKit" />
<capability name="layoutEngineVersion" value="${layoutVersion}" />
<capability name="type" value="CriOS" />
<capability name="version" value="${version}" />
<capability name="ecmascriptversion" value="3.0" />
<capability name="javascript" value="true" />
<capability name="javascriptversion" value="1.7" />
<capability name="w3cdomversion" value="1.0" />
<capability name="supportsAccesskeyAttribute" value="true" />
<capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" />
<capability name="cookies" value="true" />
<capability name="frames" value="true" />
<capability name="javaapplets" value="true" />
<capability name="supportsCallback" value="true" />
<capability name="supportsDivNoWrap" value="false" />
<capability name="supportsFileUpload" value="true" />
<capability name="supportsMaintainScrollPositionOnPostback" value="true" />
<capability name="supportsMultilineTextBoxDisplay" value="true" />
<capability name="supportsXmlHttp" value="true" />
<capability name="tables" value="true" /> </capabilities>
</browser>
<browser id="GoogleiOS" parentID="Mozilla">
<identification>
<userAgent match="iPad" />
</identification>
<capabilities>
<capability name="browser" value="GoogleiOS" />
<capability name="layoutEngine" value="WebKit" />
<capability name="layoutEngineVersion" value="${layoutVersion}" />
<capability name="type" value="GoogleiOS" />
<capability name="version" value="${version}" />
<capability name="ecmascriptversion" value="3.0" />
<capability name="javascript" value="true" />
<capability name="javascriptversion" value="1.7" />
<capability name="w3cdomversion" value="1.0" />
<capability name="supportsAccesskeyAttribute" value="true" />
<capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" />
<capability name="cookies" value="true" />
<capability name="frames" value="true" />
<capability name="javaapplets" value="true" />
<capability name="supportsCallback" value="true" />
<capability name="supportsDivNoWrap" value="false" />
<capability name="supportsFileUpload" value="true" />
<capability name="supportsMaintainScrollPositionOnPostback" value="true" />
<capability name="supportsMultilineTextBoxDisplay" value="true" />
<capability name="supportsXmlHttp" value="true" />
<capability name="tables" value="true" />
</capabilities>
</browser>
</browsers>
Points of Interest
It's important to know that it's quite difficult to get Asp.Net to reload these new browser definitions.
If updating the main browser definitions in the .Net framework folders then you'll have to restart the computer to have them applied.
If you're adding your own browser files to your application you'll have to restart IIS. I found the easiest way to do this is to run cmd.exe
as admin and then type IISReset
It's not just tablet browsers this has been a problem for. I've had IE10 create problems for the same reason. MS has released a patch which will update this for you:
http://aspnet.codeplex.com/releases/view/41420