Scott Hanselman

The .NET Framework and the Browser's UserAgent String

September 11, '08 Comments [42] Posted in ASP.NET | Programming
Sponsored By

Vote Now! One of the things I'd said I'd do, Dear Reader, when I went to work for the Big Blue Monster, was to get your feedback into The Company whenever possible. Here's another opportunity for us to effect change, however small.

A while back I made a little site called http://www.smallestdotnet.com that would look at your Browser's UserAgent

and let you know the size that the latest .NET Framework would be for you (ballpark size). In the process I've gotten to see a LOT of interesting Browser UserAgents in the IIS logs.

If you visit the site and scroll down, you'll see YOUR Browser UserAgent at the bottom. Here's mine:

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.21022; Media Center PC 5.0; Zune 2.5; MS-RTC LM 8; .NET CLR 3.0.30618)

Notice that I've got IE8 on 64-bit Windows. However, there's other stuff in there, like I have the Zune software, I have Media Center enabled, and I've got three versions of the .NET Framework. In this example, 2.0, 3.0, and 3.5.

Here's a UserAgent that showed up today on http://www.smallestdotnet.com:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.0.3705; InfoPath.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 1.1.4322; .NET CLR 3.0.04506.590; .NET CLR 3.5.20706; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; Zune 2.5; WWTClient2; MS-RTC LM 8; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)

Now, this guy is clearly a developer who has installed beta versions of things, but he's also got InfoPath and a bunch of other stuff. Still, that's a pretty crazy UserAgent and it's being transmitted all the time.

Registry Editor

UserAgents are added for IE in the Registry, as seen in the screenshot above.

Why Should You Care?

In the case of a system with IE and a lot of .NET Framework versions, ASP.NET currently truncates the UserAgent at 256 characters so my own case, the site was only getting part of the story. They might change that truncation number, but ultimately, I think we all want tidy UserAgents, right?

UserAgent length matters. Early versions of FireFox had a UserAgent Limit of 127 characters and used to return null before the bug was fixed last month and now it truncates. The FireFox plugin added when you installed .NET by default only shows the most recent .NET Framework. Do you want that functionality in .NET?

Truncated UserAgents can also mean you might get "Unknown" Back from Request.Browser.Browser. In my case, I was getting an exception from Request.Browser.ClrVersion because the truncated CLR Version was something like ".NET CLR 3.".

There's some people looking at this internally, and there's three groups involved. There's Internet Explorer, involved peripherally, there's the CLR Team and the installer that adds the values, and there's the ASP.NET team who cares because of the server-side sniffing.

Poll/Questions

Vote Now!The questions I have for you are these:

  • Do you use these .NET Framework-specific values? What for? How do they improve your site or make your user experience different?
  • If the .NET Framework-specific values were removed completely what would that mean to you or your business?
  • What if the values were conflated to show just the most recent .NET Framework?
    • Could you get the information you needed using just the value of the latest version?
  • What if the values were conflated to show just the major side-by-side CLR releases?
    • For example, 1.x, 3.5SP1 and 4.0. In that example, 3.5SP1 implies 2.x and 3.0. If you just had 2.0, you'd see 1.x, 2.0, and that'd be it.
    • Could you get the information you needed using just the value of the those major CLR/Framework versions?

Please take a moment and do this micropoll. It's ONE question with ONE vote button. Literally two seconds of your time. You can also add the poll to your blog. Also, leave comments and I'll make sure the right people seem them.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Friday, September 12, 2008 12:05:17 AM UTC
I'm shocked so many are saying "Keep All Versions." Why?
Friday, September 12, 2008 12:18:06 AM UTC
I think that for most purposes, having only the most recent version makes most sense. After all, if you have 3.5, then you also have 2.0 and 3.0 per definition, and the Traffic caused by the userAgent on both Server/Client side but also on Storage side (logging) can get quite heavy.

However, I think there should be a little tool as part of the .net SDK that allows changing this for development purposes, i.e. to see how a site reacts if you only have 2.0 or 3.0.
Friday, September 12, 2008 12:27:28 AM UTC
After all, if you have 3.5, then you also have 2.0 and 3.0 per definition


That's not true at all - there is a myriad of breaking changes between 1.0 and 3.5 - if someone only has 3.5, and your app was compiled with 1.0, it's not going to run, period.

That said, I voted for only the major versions. I think it's the best balance between information completeness and playing nice with the HTTP protocol & browsers' limitations.
Friday, September 12, 2008 12:30:40 AM UTC
Why don't the browsers, by default, return the minimal amount of into (IE, FireFox, Javascript enabled/disabled, etc) to make the web minimally functional, and then have options to determine what you want to share with the world. Maybe you could even do it site-by-site.

Why do I have to divulge all my info to every site all the time?
Friday, September 12, 2008 12:36:23 AM UTC
Greg, valid point, although I was talking about 2.0, not 1.0. I think 1.x would be its own beast. I was saying that 2.0 apps would run with 3.5 and 3.0 installed.

Chad - Did you vote?
Friday, September 12, 2008 1:35:35 AM UTC
Hmm, weird. It won't let me vote. It's only showing me the results. *shrug* :( I'm not actually sure how I'd vote. I think anything other than listing every single version will easily lead to backwards compatibility nightmares. "I'm checking for .NET 2.0 but it's failing!" ... "Oh I have .NET 3.5 installed." ... "Well, that wasn't out when I deployed six months ago. Yargh."

What about .NET 3.5 SP1 Client Profile? How does that show up in the user agent string?

I think something that would be great is if we had some javascript samples to help us build a better download page. The scenario I'm thinking of is for Paint.NET v4, where I have "install" and "update" ZIP files. The latter saves 2 MB, and it'd be nice if I could auto-detect which one is appropriate for the user and just not show the other parts of the download list. As it is now, I'll only be putting the "install" ZIP up for public consumption, simply to avoid any possible confusion. It's probably really easy, I just have never written any Javascript :)
Friday, September 12, 2008 1:56:16 AM UTC
Greg, valid point, although I was talking about 2.0, not 1.0. I think 1.x would be its own beast. I was saying that 2.0 apps would run with 3.5 and 3.0 installed.


That's certainly true for now, CLR-wise vs. Framework-wise - but will that remain the same going into 4.0? Granted, you'd know more about this than I, but surely the CLR will hit a v3 sooner or later.
Friday, September 12, 2008 2:05:47 AM UTC
Like Rick, I cannot vote .. only view the results. was there a time period and voting is closed?
Friday, September 12, 2008 2:17:59 AM UTC
The only reason I would need that info at all is if I wanted to show people whether or not they had the prerequisites for running my software. Is there some freely available widget that'll take a target framework version and either tell people they're good to go or provide a minimal framework download link?
Friday, September 12, 2008 3:36:04 AM UTC
No time period, and votes are still coming in. I'll check to see if there's a problem.

Rick - What if you could use Javascript, rather than a UserAgent string?
Friday, September 12, 2008 4:52:37 AM UTC
@Scott: Yep, voted. Show everything was my vote (why the heck not, they're giving away everything else)!

It just seems like this should be an easily configurable option and the user should have the choice how much they're willing to divulge.
Friday, September 12, 2008 5:47:30 AM UTC
"Rick - What if you could use Javascript, rather than a UserAgent string?"

Umm ... I don't know. I quite honestly don't really know much about web page development, I guess I got things crossed a bit with my request there :) I suppose it'd make sense that client-side JavaScript could have a function to detect .NET better than server-side parsing of a UserAgent string.
Friday, September 12, 2008 7:01:45 AM UTC
I'd REALLY like to understand HOW people are using "all the framework versions" and why you'd care. I can't reconcile why there are so many people voting for that first option.
Friday, September 12, 2008 7:16:07 AM UTC
It's not letting me vote either.

Personally I'm not entirely sure why it needs to be there at all; no other plugin needs to broadcast itself on every single request.

Useragent sniffing in general (IMHO) is a bad idea - look at what it has lead us towards (have you seen the Chrome useragent!) - feature sniffing is a much better idea, instead of maintaining a un-maintantanble database of sniffing goo.
Fowl
Friday, September 12, 2008 7:29:14 AM UTC
Can't vote either, but I think poll needs one more option: don't care. :-)
Friday, September 12, 2008 7:45:56 AM UTC
Your micropoll doesn't work on Chrome. It insists on saying Please choose an option while I've selected Keep JUST the MAJOR Side by Side versions
Kambiz
Friday, September 12, 2008 7:52:21 AM UTC
I think it's a better idea to provide a javascript detection method than exploding the user agent. What can a website do when it knows you're using .Net?
Kambiz
Friday, September 12, 2008 8:35:13 AM UTC
For the time being, it's probably better to keep the side-by-side versions.
Is this information is appropriate within the useragent string at all? Really, the main reasons of interest are with regards a) Browser market share marketing (Oh no! IE's lost another % & the like) b) Sniffing to get round bugs or take advantage of upcoming features like CSS3 etc.
a) is only of interest to fanbois and the popular press, and they're only interested in the browser; not the framework
b) suggests that everything but the browser name and version number should be moved into content negotiation - do you do javascript 1.2? do you have framework version x? etc etc It would be very nice to then use this to allow things within javascript like if(object-support[".NET3.5"])...
Sniffing based entirely on user agent is very wrong anyway. Not for nothing have browsers like Opera had to do agent string spoofing [ Oh, I'm sorry; the only browsers I "support" are..., when really all I need is DOM level 2 ]
Richard
Friday, September 12, 2008 9:02:45 AM UTC
Hello Scott,
I strongly agree with what you are asking. I think there should be a tool which should give you statics of All .NET Framework related things on a Machine. Lets say I wish that that tool should do these things -

1. Show all .NET versions installed, together with any fixes or service packs
2. Which one of them is not required, as a higher version is installed. I think they are backward compatible ( Right ? )
3. How many web sites are there on IIS and which one is using .NET frameowrks, and what are there versions. And we dive deep into this we should check markup and report any web site is not using correct right version.

Also I still find people asking very strange things about .NET framework, Still people do not know that Version of CLR hardly changes. There should be more details about the Framework and its components.
Now these days people just try to know what is ASP.NET or Winform, What is AJAX and how we can use that in ASP.Net. I strongly recommend that there should be one more section or pointers on ASP.NET web site for .NET framework ( Both CLR and Class Libraries ).

Atleast people should know what and where they are programming.
Thank You,
Shail
Shail
Friday, September 12, 2008 12:07:30 PM UTC
It should emit only the recent versions. Let's say, I go to smallestdotnet and try to download a version, now surely you dont want me to download .net 1.1 or in other words you give the different sets of current CLR version so why my browser should ever bother to send UserAgent : .NET CLR 1.1.4322.

May be bit insane, i was thinking if there was a proactive UserAgent, like host requests to server , server send me a response code with some messsage "i need this version of this product from you". Now, in the second request host sends, "yes i have". If there is match then only server processes the request :-).
Friday, September 12, 2008 12:17:37 PM UTC
I must be missing something, but why would say my ASP.Net website be interested in if the end user has .Net on their machine and what version they have?
Gavin Draper
Friday, September 12, 2008 1:19:16 PM UTC
Who trusts the information from those fields anyways? Unless I'm doing something for an intranet app, I don't believe anything coming from the user, including those fields.
HB
Friday, September 12, 2008 2:00:26 PM UTC
I am not sure that the .Net version should be in the User Agent at all. Even if so, I fail to see why you would want to transmit all versions.

I also don't understand why .NET 3.5 would install next to 2.0 rather than on top of it. Keeping separate installs to 1.1 and 2.0 I can understand, since there are CLR changes, and a 1.1 app may not work in 2.0, but I see no reason to keep 2.0 and 3.5 separate. Even if there is a good reason for this, I don't see a reason to send both versions, since 3.5 is a superset of 2.0.

Regardless, presuming there is a good reason to send all .NET versions, you could shorten them a bit. To start, remove the "CLR" from all of them. .NET CLR doesn't give you any more information than does just .NET. Secondly, shorten the version numbers. Sending .NET 3.5 is sufficient. I personally don't care that it is really .NET 3.5.22012 since -- unless I am mistaken -- there is no public release 3.5.22013. You said yourself that the guy clearly installed betas. Since your app shouldn't be targeting beta versions anyway, it doesn't convey any additional useful information.
Aaron Davis
Friday, September 12, 2008 2:01:14 PM UTC
Why are you so shocked that so many people would want all of the Scott? It's like asking a marketing guy whether you want to turn something that they don't necessarily like into an option on a tab sheet. They always say yes, because they're afraid that at some point down the line they'll have a customer who will want to turn something they don't like off, and want to be able to tell their customer they can do that.

For as much as developers hate that when marketing/business types do it to us, we want the same flexibility even though we can't identify a reason at this moment.
Friday, September 12, 2008 2:36:26 PM UTC
i personally think (and voted for) removing it...

while i can understand why developers would want this information i see no need for it being pushed (or really pulled) in every single request.
furthermore i see no need in web based applications (i also often get worried about proxy servers and the information that they send down the pipe)

if you want that information to ensure that the user downloads the right version of your software (and you can support all of the different versions) then why wouldn't you first have an MSI package that determines what the client can support and then pulls (or downloads) the right version instead of trying to sniff it via UserAgent?
Friday, September 12, 2008 2:38:24 PM UTC
Scott,

In FireFox 3.0.1 I can not vote. It seems to think I have already voted. However, in IE7 I am given the radio buttons and the vote button.

BOb
PilotBob
Friday, September 12, 2008 2:42:17 PM UTC
Why do we need to pollute the "User-Agent" string, which after all is meant to describe the "agent" that is displaying web pages to the "user", with .NET versions, Zune software and the like in the first place?

It is not as if we are running out of HTTP headers. IE can lead the way by choosing a header (like "X-NET-Version:") and dump anything it wants there. The server-side applications that are interested in this information (like www.smallestdotnet.com) would learn to parse this header.

A similar thing is already being done on the server side with the "X-Powered-By: ASP.NET" header pushed out by IIS.
Friday, September 12, 2008 3:10:49 PM UTC
What will the long-term effect be if we keep putting all the installed components into a UA string? Even if we have .NET (which has minimal support outside of Windows), what about Java, Python, addons, Office applications...how many should we be adding? It would seem to make more sense to just have a special "Do you support X" header sent from the server and have a more general mechanism for reporting installed components (which the user could control via preferences) rather than using a huge string transmitted with every request.
Friday, September 12, 2008 3:35:59 PM UTC
I want to be able to control what a sniffer knows about my browser. Whether using UserAgent or through Javascript although right now it seems I can control the UserAgent only.

If UserAgent space is limited, how about squeezing the info.

.NET CLR 2.0.50727,3.0.04506.30, 1.1.4322, 3.0.04506.590, 3.5.20706, 3.0.04506.648, 3.5.21022;....

instead of

NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 1.1.4322; .NET CLR 3.0.04506.590; .NET CLR 3.5.20706; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022;

Abdu
Friday, September 12, 2008 3:38:45 PM UTC
@Scott-

I have a scenario question for you. If you have a webserver that has .Net 2.0 installed (NOT 3.0 / 3.5) and a web surfer, called "Bob", comes in. Bob has version 3.5 installed. If Bob's browser used the conflated .Net user agent string of ("3.5") how does the webserver know that 3.5 will work with 2.0? If the webserver thinks that it can't use 2.0 would it not perform the way it is supposed to?

Yes one could check to see if Bob's version is greater than 2.0. But what happens if .Net 4.0 comes out that uses a different CLR and makes it not work with 2.0. The same way 1.1 doesn't work with 2.0.

-Chris
Chris
Friday, September 12, 2008 3:42:13 PM UTC
@Abdu - I like your "squeezing" method. It goes with the DRY principle.
Chris
Friday, September 12, 2008 5:05:27 PM UTC
Hey .. love ur work at smallest dot net.... a lil update though... now since crome has joined the infamous browser group i guess the site must now interpret info comming from The New User Agent... this is what it says when I visit with crome -->
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13"
varun
Friday, September 12, 2008 5:12:38 PM UTC
@Abdu

In that method you can't cleanly split it. That's only a band-aid anyway.

I think the method of using UserAgent is broken...I treat UserAgent like user input and don't trust it anyway. The only reason I can think that my web app would care at all if .Net is installed, is if I had a Click Once application and I didn't even want to bother displaying a link to that application if they don't have .Net installed...that's certainly an edge case but it's there I guess... But really a web app shouldn't give a care about my .Net version or lack thereof.

BTW Scott...I can't login with Yahoo's OpenID...I get a 404 on your site.
Ryan
Friday, September 12, 2008 5:21:47 PM UTC
The first part of any .net app is an auto-updater. This is how backward compatibility issues are avoided (not to mention changes in code, policy, etc.).

Fewer .net versions on your users' system means fewer headaches for you and better system performance for them. How many of the same service needs to be polling/logging events. One should do. Even if you'd like the previous 'stable' version to fall back to if a nasty bug or security issue is discovered in the latest; it's most likely going to be in the previous as well. But the auto-updater could remove the broken one then install a hopefully stable/secure runtime and a freshly compiled application from a hot-fix branch of the source tree.

Besides, it's the .net team's job to gracefully depreciate when changes are made. Removing the redundancy would mean fewer targets for viral & malware. Unfortunately for MS users would remain content with their system's performance and upgrade hardware less frequently.

Just my opinion and I'm no expert as I still can't figure out how to uninstall Internet Explorer or make applications render html in Firefox without breaking my system.

Tush
Friday, September 12, 2008 5:26:42 PM UTC
@Jason

If you are running XP, just install Beta 1 of IE8 (if you can still find it) this apparently nukes IE7, and then Install Beta 2 of IE8....after the setup of IE8B2 is complete, don't reboot...you'll have a system with no IE at all...you can probably then alter the startup not to do the second part of the B2 install. Haven't tried that yet...but had a nice 20 minutes there where there was no IE7/8 anywhere to be found. I haven't tried to repeat this but it was fun for a moment or two.
Ryan
Friday, September 12, 2008 6:01:11 PM UTC
Voted to not show anything. There is no legitimate reason for me to tell every website I go to what versions of .NET I have installed. The security implications of this are unacceptable, particularly since it's wrapped (with Firefox at least) with ClickOnce. Now, I have the ability to serve up custom .NET Exploit code. Awesome.
Friday, September 12, 2008 11:25:33 PM UTC
Great question!

Do you have any data on what percentage of web requests use this information?

Unfortunately, the header is sent on every request for html pages, javascript downloads, images, etc. This is horribly wasteful! A single request to download the CNN home page will send this data ~150 times (CNN has about 150 subresources on its home page). For the example you listed above, with ~250B of extraneous information, that is ~37,500 bytes! That means that using Internet Explorer (the only browser which sends these headers) over dialup (128kbps) will download CNN pages in at least 2.34 seconds slower than with any other browser! All to transmit data which CNN never uses. Wow!

I think a better solution should be sought. (And to be honest, I'm not sure what problem is being solved anyway).




Tuesday, September 16, 2008 12:07:43 AM UTC
Hello there,

I've never installed any .NET betas as the guy you've mentioned. I've installed, chronologically:
.NET 2.0
.NET 2.0 SP1
.NET 3.0
.NET 3.0 SP1
.NET 3.5
.NET 3.5 SP1
Always running the full redistributable packages, never the bootstrappers.

My user agent string now looks like:
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)

Three versions of .NET 3.0? Two versions of .NET 3.5? Weird.
Is it normal/possible? I'm confused..
Vinicius
Thursday, September 18, 2008 2:27:16 PM UTC
I too wonder a) why anyone would need this information on the server side (isn't the whole point of the web and browser standards to decouple client and server?), and b) if for some reason it is necessary, isn't there a better place to put this information than in the user agent? Seems like someone back in the early days decided to use User Agent as a shortcut, and now its stuck there. Surely an http header would be a better place?
Tuesday, September 23, 2008 10:05:14 AM UTC
The user agent string is not really a nice thing. Why is it needed at all? It's needed because different browsers support standards differently. It's needed because those guys who build browsers don't follow the standards in the same way.

I'm so fed up with writing conditional code to render my page differently for different browsers, and writing javascript that has to navigate a DOM differently for different browsers. It's a pain in the proverbial.

The only reason I MIGHT still want to see this, is so I can render a mobile site. Or to know if a browser supports HTML4 or 5 (in due course).
Wanting to know what CLR version runs on a machine (when it can be spoofed so easily anyway)? I just don't see the point. I agree with David Nelson here.

OTOH, having some Javascript to query machine specific options I'd be cool with. Determine on the client side, not the server side what can be supported and redirect, or append POST or QueryString variables accordingly.

Sadly the web is not a perfect place yet.
Thursday, September 25, 2008 3:11:02 AM UTC
I also don't see the point in including the CLR version in the user agent string. Why not also include the installed version of Flash, MS Office, Anti Virus, Visual Studio, DirectX ... :-) The only piece of information that needs to be in the user agent string is the browser and version. Instead of my current Firefox user agent string:

"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 (.NET CLR 3.5.30729)"

Just make it: Firefox/3.0.1

Same thing with IE. This guy's post (step 1) strikes a chord with me.
Saturday, November 01, 2008 7:25:44 AM UTC
I guess I am one of those people that "install betas" because my user agent is: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.590; FDM; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 2.0.50727; .NET CLR 3.5.30428; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; WWTClient2)", it looks like I have 4 3.0's, and 2 3.5's... curious, and unnecessary.

But what would be really helpful is if there was a way to determine if Silverlight was installed (maybe with it's corresponding CLR), so I can track statistics of those that visit my companies web site (and prove to my boss that most of our customers already have Silverlight installed).
Brad
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.