I was recently assigned a support ticket from a user who was unable to log into Contensis. Having spent a number of hours resolving the issue I thought I would share the knowledge.
Contensis is a browser-based CMS that currently supports a number of browsers, one of which is Firefox 3.5+. When I initially started looking at this issue my initial thought was that the user was using a previous version of Firexfox. It turned out the user was using Firefox 3.6.3, so the browser version wasn't the problem. Our software determines a users’ browser version using the following standard .NET property:
Basically, behind the scenes the user agent from the client is parsed and the major version along with other information is extracted using various regular expressions that are defined in .browser files. These files are stored in:
So having established the above, the next step was to determine the clients’ user agent. To do this there is a very useful site that you can point people to:
The clients’ user agent turned out to be:
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:184.108.40.206) Gecko/20100423 Ubuntu/10.4 (lucid) Firefox/3.6.3
Now the next logical step was to examine the .browser files to determine which regular expression was designed to handle this particular user agent. In fact, herein lies the problem, there isn’t a regular expression in the mozilla.browser file that would handle the above user agent. The problem stems from the fact that there is no official standard for user agents, there is an unofficial standard which is as follows:
Mozilla/[version] ([system and browser information]) [platform] ([platform details]) [extensions]
This unofficial standard has been adopted in Firefox 4 as you can see from the following reference for Gecko 2.0 based applications:
And so the plot thickens, it would seem as though our clients’ user agent does not adhere to the ‘unofficial’ standard, and therefore Microsoft didn’t cater for this user agent in the .browser files. I’ll leave it to you to decide where the blame lies.
Interestingly, this issue only applies to .Net Frameworks 1 - 3.5 sp1 as the .browser files have been changed quite substantially in .Net 4 and from initial investigation seem to be a bit less specific with their regular expressions.
So to the fix. There are two ways to fix this issue. You can either:
- add an additional regular expression to the mozilla.browser file
- update an existing entry so the regular expression will match the user agent.
I’ll explain how to update an existing entry below. If you fancy having a go at adding a new entry from scratch then you will find the following reference http://msdn.microsoft.com/en-us/library/ms228122(v=VS.90).aspx useful.
Microsoft do state that you shouldn’t update the .browser files as they can get overwritten as part of service pack releases, however if we apply some common sense to the situation when/if Microsoft update these files for .NET 2 they would more than likely fix this ‘issue’ and therefore we would be happy for our change to be overwritten. I have even found a forum post from a member of the Microsoft IIS Product team where he admits that it is fine to update the files as “we're not aggressive in updating these files because they are user editable’’.
Having decided to modify an existing entry the initial step was to identify which entry to modify, looking through the mozilla.browser file it soon became obvious that the regular expression on line 188 was designed to catch this user agent, the original regular expression is:
Going back to the user agent string the issue is actually the placement of Ubuntu/10.4 (lucid), therefore to fix the issue we can update the regular expression to:
As a side note, this is pretty much identical to the implementation in .NET 4.
How to apply the change
You would hope that at this stage things would get easy, but as we all know, when it comes to IT nothing is ever simple.
Here are the steps involved to ensure that the change is applied. I have tried omitting steps out of this process but I can assure you that every step is required in order to apply the change:
- Update the mozilla.browser file as detailed above
- Open a command prompt and run the following commands:
Running the above tool parses and compiles all the browser definitions into an assembly and installs the assembly into the global assembly cache.
- You then need to stop IIS
- Once IIS is stopped you can then delete the temporary ASP.Net files. The temporary ASP.Net files can be found in:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files
Just delete the folder called ‘root’ from within the above directory
- Finally, start IIS.
You should now find that the correct information is returned when using the Request.Browser.MajorVersion.
So that's how to resolve ASP.NET's occasional mishandling of user agents - I hope this has saved you the hours of investigation that it took me! I welcome any questions or comments please post them below.