A few days ago I got an interesting case with a customer who intermittently kept getting a download box with Safari and a similar one telling him that he has choosen to open Default.aspx, do you want to open or save the file, when browsing the site with FireFox.
In IE it sometimes came back with the following message
The XML page cannot be displayed
Cannot view XML input using style sheet. Please correct the error
and then click the Refresh button, or try again later.
Invalid at the top level of the document. Error processing
resource ‘http://localhost/TestApp/Default.aspx’. Line 1, Positi…
This problem had started occurring on the site after upgrading to .NET Framework 2.0 on the site.
Troubleshooting the problem:
The customer had really done his part when it came to troubleshooting, and using Fiddler (a really nice tool for debugging HTTP traffic btw), he had discovered that when all went well the results were returned as text/html, but when things went bad, they came back as text/vnd.wap.wml.
The question was only why?… and why the difference between 1.1 and 2.0?
Since I have already written the cause in the title I’m sure you already figured out what happened, but it took us a while to get the crucial pieces of information regarding the output caching and the mobile browsers.
The page that had the issue had OutputCache turned on with a header similar to the following…
<%@ OutputCache Duration=”25″ VaryByParam=”None” %>
There is nothing really strange there, it just caches the output for 25 seconds…
The problem is that it caches independently of which browser you are using so if your cache has just expired and then you browse to the page with a mobile phone, the cached output will be based on the settings you have for this phone.
For example for a browser with the following user-agent “Microsoft-SmartPhone/3.0 SonyEricssonM600i/R100 Profile/MIDP-2.0 Configuration/CLDC-1.1” it rendered the page using an XhtmlTextWriter and the output mime type was text/vnd.wap.wml.
Later on when browsing the page with FireFox we got the same cached copy, still with a mime type of text/vnd.wap.wml and since the browser didn’t recognize the mime-type it asked to save or open.
Now, why is this different in 2.0? I am not exactly sure why at the moment, but what I do know that the way browser detection is done has changed between versions…
“Browser definition files are new in the .NET Framework version 2.0. In earlier versions of the .NET Framework, the browserCaps element was used to define browser definitions in configuration files.”
And my guess is that in 1.1 there were probably no browsers with a prefered rendering method of wml. However, one thing to note here is that in this case we happened to pick up a wml capable browser at the caching moment. A similar issue would have occurred if someone browsed with a low-level browser at the caching moment, in which case our page would have rendered completely different than we are used to in IE for example.
To resolve the issue you need to make sure that you vary by browser, i.e. create a different cached copy per browser type, and the way to do that is to include a VaryByCustom=”Browser” in the OutputCache statement.
An alternative for the mobile browsers would be to create some type of url redirection based on browser capabilities or user-agent, but you could still face other such as weird rendering and exceptions in low-level browsers that don’t understand DHTML, depending on what browser happened to get in when you cached.
My customer in this case has yet to test and verify the solution on his main site, but since I could reproduce this easily on my machine and know that it can cause this issue I figured it is worth writing about anyways.
Until next time,