I just had an exchange with a fellow journeyman .NET developer, let's call him "Ed", on a friendly community mailing list. It went something like this (greatly abridged -- the real exchange was a bit more lengthy, and polite ;-)...
- Ed:
- I'm trying to host .NET UserControls on a secure (https:) website, and it doesn't work. Does IE not support this?
- Me:
- Do you have a clue? SSL is hard.
- Ed:
- Yes, I most certainly have a clue. My SSL configuration is a thing of beauty. The whole site works over https: except for the UserControl downloads.
- Me:
- Ok, ok, you know I had to ask. Now, what's the problem, exactly?
- Ed:
- I'm getting the "this page contains secure and non-secure items" message. The warning goes away when I comment-out the <object> tag for the control, so it must be something related to the UserControl.
- Me:
- Can you show us your <object> tag? It's not that you're still specifying http: in the classid attribute, are you?
- Ed:
- D'oh!
For the uninitiated, Ed is talking about hosting .NET UserControl classes in Internet Explorer. Jay Allen wrote the definitive treatment on this, for MSDN Magazine, a couple of years ago.
Ed got trapped by the vast majority of sample code out there (but not Jay's) which uses the http: protocol prefix, even when specifying a relative path to the assembly. What's up with that? That foolish practice caused Ed to waste a lot of time!
Let's recap. This is your page:
<object classid="MyUserControls.dll#MyUserControls.UserControl1"
width="300" height="200">
Sorry, your browser doesn't dig on .NET controls.
</object>
And this is your page, on drugs:
<object classid="http:MyUserControls.dll#MyUserControls.UserControl1"
width="300" height="200">
Sorry, your browser doesn't dig on .NET controls.
</object>
Where and how did this trend start? Is there a method to the madness?
Whenever I saw the http: prefix, I'd always assumed that it is the way it is for a reason -- to remove ambiguity for the parser. Put simply, I reckoned Internet Explorer needed this hint in order to better distinguish between an old-style ActiveX ProgId and a new-style .NET UserControl typename, when it parses the classid attribute.
But on further thought, I'm left to wonder why MS felt it was necessary to overload the classid attribute in the first place -- and even so, why didn't they give us some new, inert, and unambiguous prefix, like usercontrol: or dotnet:, to declare that we're about to specify a relative URL to a downloadable type, instead of an ActiveX ProgId? There is plenty of precedent for this -- even ActiveX controls sometimes use a classid: prefix, to hint that they're specifying a GUID rather than a ProgID.
<object classid="clsid:8E27C92B-1264-101C-8A2F-040224009C02"
width="300" height="200">
Congratulations, you've disabled ActiveX controls!
</object>And there are certainly other options. What happened to the <object> tag's codebase
and codetype attributes? Isn't this kind of thing -- determining where
to get the object and what to do with it -- exactly what those attributes are intended
for?
A little research reveals several alternative design choices, all without venturing away from the HTML 4.0 standard: http://www.w3.org/TR/REC-html40/struct/objects.html#edef-OBJECT
Look at what's recommended for Java applets these days, for example: http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.3.3
This approach looks perfectly amenable to .NET UserControls -- simply replace the java: prefix with clr: or mscor: or something.
Please, Microsoft, if you're listening -- stop overloading new semantics onto already desperately overloaded HTML tags, ok? Especially the tags that you're responsible for. It's distressing to see that Java makes better use of the <object> tag's classid attribute than .NET does.
