Cause a little O just ain’t big enough!
RSS icon Home icon
  • ASP:Menu control broken in Safari Browser in ASP 2.0

    Posted on December 31st, 2006 Big-O No comments

    I recently built a shiny new web site using ASP.NET 2.0 and thought it was all finished until I looked at the home page in the Safari browser from an Apple Mac computer. The site uses the new asp:menu control and it looked horrid in Safari. There were actually bare html tags showing up on the top of the page!

    At first I thought it had to either be my code or the data populating the menu that wasn’t compatible with Safari, but when I viewed the source of the page from within Safari I noticed that the html was totally different than the code that IE was getting. I knew that it wasn’t my code doing any kind of browser detection, so that meant that ASP.NET was dynamically generating incompatible code at run time. There was a lot more to the asp:menu control than I thought.

    It turns out the asp:menu control is designed to be able to gracefully handle older browsers for you and do things like detect if the browser can’t support JavaScript and if so it will only generate html menus. So, that means that ASP.NET incorrectly thinks that Safari can’t handle the dynamic menus and is sending it downgraded code that renders like crap.

    To fix this you are going to have to get your admin hat on because you need to edit some files in your %system% directory. Your web.config and machine.config files have sections called “Browser Caps” that define for it what browsers can do what. Starting with ASP.NET 2.0 the settings are also contained within files with the .browser extension that you can find at:

    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers

    The browser caps sections are still supported for backward compatibility. The sections that affect the display of the asp:menu control for Safari are found in the mozilla.browser file in that directory. When looking through there I was confused at first because everything seemed to have sensible settings, but I finally found the culprit. Underneath this section:

    <browser id=”Safari” parentID=”Gecko”>

    You will find this little guy:

    <controlAdapters>
        <adapter controlType=”System.Web.UI.WebControls.Menu” adapterType=”System.Web.UI.WebControls.Adapters.MenuAdapter” />
    </controlAdapters>

    Apparently the ASP.NET 2.0 menu control has a system of “adapters” that do the generation of the back-versioned code. I’m sure you can access and modify those adapters or create your own, but I haven’t bothered to research how to do it because I knew that the menu worked fine in Firefox and should be working fine in Safari, so I just removed the controlAdapter section from the Safari browser section of the config file. This will cause the behavior to be inherited from the parent, which in this case is Gecko which happens to be the same parent that Firefox inherits from in that file.

    After removing that section there is one last step. Unlike the web.config, ASP.NET will not automatically read the changes to the .browser files and change the behavior of your web site. I tried bouncing IIS, as well as rebooting before doing a bit more research and finding out that there is an ASP utility called Aspnet_regbrowsers.exe that you need to run that will take those .browser files and compile them into a dll called ASP.BrowserCapsFactory.dll that gets placed in the same directory as the .browser files. The information also gets placed in the global assembly cache so you don’t have to bounce IIS in order to get the changes to take affect after running the tool. To compile the files issue the following command from a command prompt:

    c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regbrowsers.exe -i

    If you take another look in the Browsers folder you will see the addition of three files. BrowserCapsFactory.cs, ASP.BrowserCapsFactory.dll, and browserCaps.token. If you now try your page again in Safari you should see better results. Or at least I did.

    This problem is a classic example of the hidden costs associated with developing with Microsoft software, and also a perfect example of the advantages of an open source community model. This whole system was designed by Microsoft so that developers could keep up with the mobile market that is rapidly changing and becoming increasingly online. At first they were going to keep the .browser files up to date but eventually didn’t want to keep up with all the changes so they just dropped it. The .browser files are sitting dormant, and if you are just now making the switch to ASP 2.0 from 1.1, the settings for Safari (and probably a lot of the other ones) are out of date before you even install the software. If this was an open source project, the community would be keeping them up to date. As soon as a new device or browser hit the market, the developers that had to code for it would be submitting the correct browser definition file for it.

    Here is an official Microsoft statement about this:

    Q: Why will Microsoft not provide device specific updates?

    A: Our original plan was to provide regular updates, however, based on the evolution of the market we needed to change our approach in order to better address the rapid proliferation of different kinds of devices around the world…If customers would like assistance with building support we can put them in touch with 3rd party companies who specialize in mobile development with ASP.NET, or with Microsoft PSS.

    Or in other words, do it yourself or pay someone else to do it. I bet your CTO didn’t cover that in his budget proposal!

    Leave a reply

    You must be logged in to post a comment.