Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 / Safari 8 not working with ASP.NET AJAX-Extensions

Our website suddenly stopped working when iOS 8 was rolled out. Every post-back from within an ASP.NET UpdatePanel leads to an empty page. It still works, if the user-agent is set to "Chrome" from within Safari 8 (on Mac).

I already tracked down, that some of the "ScriptResource.axd" and "WebResource.axd" files are not loaded at all. There is also an error telling "Sys.WebForms" is undefined (probably due to the missing script-files).

We are using ASP.NET 2.0 with AJAX-Extensions 1.0 (I know, quite outdated. But used to work or could be fixed until now).

like image 743
Tobias81 Avatar asked Sep 22 '14 16:09

Tobias81


3 Answers

Beware that this solution is only applicable to .NET version < 4.0

So here it is...

Working UA: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36

Not working UA: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10

The problem lies in the major version-change to AppleWebKit/600. ASP.NET AJAX does not correctly recognize the new Safari 8 browser (also with iOS 8). It thinks, that there is no support for partial-rendering. I found it in those lines from "PageRequestManager.cs":

bool supportsPartialRendering = (browser.W3CDomVersion >= MinimumW3CDomVersion) && (browser.EcmaScriptVersion >= MinimumEcmaScriptVersion) && browser.SupportsCallback;

MinimumEcmaScriptVersion/MinimumW3CDomVersion are both 1. Request.Browser gave me the following result:

W3CDomVersion = 1.0
EcmaScriptVersion = 1.0
SupportsCallback = false

Even though "EcmaScriptVersion" has a strange value, the problem is mainly caused by SupportsCallback beeing false.

The bug lies in the "mozilla.browser" file that ships with ASP.NET (located somewhere in "C:\Windows\Microsoft.NET"):

<browser id="Safari60" parentID="Safari">
  <identification>
    <capability name="appleWebTechnologyVersion" match="60" />
</identification>
<capture>
</capture>
<capabilities>
  <capability name="ecmascriptversion"       value="1.0" />
  </capabilities>
</browser>

<browser id="Safari85" parentID="Safari">
  <identification>
    <capability name="appleWebTechnologyVersion" match="85" />
  </identification>
  <capture>
  </capture>
  <capabilities>
    <capability name="ecmascriptversion"       value="1.4" />
  </capabilities>
</browser>

<browser id="Safari1Plus" parentID="Safari">
  <identification>
    <capability name="appleWebTechnologyVersion" match="\d\d\d" />
  </identification>
  <capture>
  </capture>
  <capabilities>
    <capability name="ecmascriptversion"       value="1.4" />
    <capability name="w3cdomversion"           value="1.0" />
    <capability name="supportsCallback"        value="true" />
  </capabilities>
</browser>

Everything newer than "Safari 85" was meant to be catched by the last definition. But due to a messed-up regular expression, "Safari 600" is falsly detected as "Safari60":

<capability name="appleWebTechnologyVersion" match="60" />

Should have been

<capability name="appleWebTechnologyVersion" match="60$" />

I resolved this issue by adding a custom file "App_Browsers\safari.browser" to my application with the following content:

<browsers>
  <browser id="Safari60_bugfix" parentID="Safari60">
    <identification>
      <capability name="appleWebTechnologyVersion" match="^\d{3,}$" />  <!-- At least 3 digits -->
    </identification>

    <capabilities>
      <!-- Same as in "Safari1Plus" -->
      <capability name="ecmascriptversion" value="1.4" />
      <capability name="w3cdomversion" value="1.0" />
      <capability name="supportsCallback" value="true" />
     </capabilities>
  </browser>

  <browser id="Safari85_bugfix" parentID="Safari85">
    <identification>
      <capability name="appleWebTechnologyVersion" match="^\d{3,}$" />  <!-- At least 3 digits -->
    </identification>

    <capabilities>
      <!-- Same as in "Safari1Plus" -->
      <capability name="ecmascriptversion" value="1.4" />
      <capability name="w3cdomversion" value="1.0" />
      <capability name="supportsCallback" value="true" />
    </capabilities>
  </browser>
</browsers>
like image 111
Tobias81 Avatar answered Nov 12 '22 03:11

Tobias81


The issue reproduces only when one uses the custom browser capability feature, i.e. one has .browser files in his/her \App_Browsers folder. The reason is that: Microsoft once released a fix (see http://support.microsoft.com/kb/2836946 for more details) which addressed some browser capability issues including the issue we are seeing here; however, the fix would not be in effect when one uses the custom browser capability feature due to compatibility issues. Therefore, for anyone who uses custom browser capability files, unfortunately, the best way to resolve the reported issue is to adopt the workaround provided by Tobias81.

like image 29
X-Mao Avatar answered Nov 12 '22 02:11

X-Mao


I implemented the solution mentioned above by @Tobias81 and I got a "The browser or gateway element with ID 'Safari60' cannot be found" error. I therefore fixed the issue by changing the element in my application's web.config to match the newer version and assign the correct capabilities.

<configuration>   
  <system.web>     
    <browserCaps>       
      <filter>
        <case match="AppleWebKit/600">EcmaScriptVersion = 1.5           
          supportsCallback = true         
        </case>       
      </filter>     
    </browserCaps>   
  </system.web>
</configuration>
like image 2
Ajit Goel Avatar answered Nov 12 '22 03:11

Ajit Goel