.NET Framework 2.0 - first impressions
Today Microsoft released .NET Framework 2.0. I already managed to convert this site and homokaasu.org
to run on it. I didn't yet install it on the server, though, but got it
running on my home computer. It was quite easy, but not as fluent as it
could have been. Here
are the first problems I've encountered and their solutions.
Extension mapping with build providers
Definition for extension mappings seems to have changed. Fw 2.0
introduces a design called BuildProvider, which take care of compiling
the source code for different purposes on a web site. There are build
providers for normal pages, user controls, master pages, web services
and so on (check the full list at the machine.config file).
In addition to IIS mapping and http handler definition, non-standard
extensions must be defined in a third place: inside the compilation tag
of the web.config file, like this.
<compilation debug="true" batch="true" batchTimeout="120">
<add extension=".gas" type="System.Web.Compilation.PageBuildProvider" />
The System.Web.Compilation.PageBuildProvider is the default build provider for aspx files and is used here. In this case, gas files are treated exactly as aspx files.
Creating IHttpHandler instances
For some reason, when creating the pages on the fly for wildcard
extensions in this blog application as I previously described, the
PageParser class used to create the IHttpHandlers (Page objects) fails
with a null reference exception. I tracked the problem with Reflector
and it seems that this depends on a new HostingEnvironment class, which
is null at this point of the page lifecycle in 2.0.
This could have become nasty, but luckily the solution is quite
easy. I noticed that the BuildManager has a method called
CreateInstanceFromVirtualPath which appears to be very promising. It
has two parameters: string virtualpath and Type requiredBaseType, which sound good, but it returns an Object. I made a guess and replaced...
return PageParser.GetCompiledPageInstance("/scaffold.aspx", Context.Server.MapPath("/scaffold.aspx"), Context);
return BuildManager.CreateInstanceFromVirtualPath("/scaffold.aspx", typeof(Page)) as IHttpHandler;
...in my PageHandlerFactory class definition and w00t! We get signal!
A bit sloppy though
Technically the framework seems to work well, but the adjoining
information (documentation, error messages, comments in config files)
is somewhat slipshod. For example, when I heeded this error message...
There is no build provider registered for the extension '.gas'. You can register one in the <compilation><buildProviders> section in machine.config or web.config. Make sure is[sic] has a BuildProviderAppliesToAttribute attribute which includes the value 'Web' or 'All'
...by adding the definition and made very sure the appliesTo attribute was included, I was greeted with the following:
Unrecognized attribute 'appliesTo'. Note that attribute names are case-sensitive.
The end result was that the attribute wasn't needed, in fact, mustn't
be there, although the error message and documentation told exactly the opposite.
The SDK documentation has dead links (and a very bland look).
Other noteworthy things
Aww... namespace attribute of @register directive is
now case sensitive. Too bad for the sloppy developers who didn't notice
the case inconsistency in namespaces and references before this...
MySql Connector/Net works (with MySql 5). Nant works but requires some directory name changes in it's config file. SharpDevelop works and recognizes the new framework automatically.
My multiuser game/chat server works perfectly. Unlike with the
web apps, the complier didn't warn about anything obsolete. The server
uses threading, xml and tcp-level network objects very extensively so
it seems it is the web part of the framework that has experienced the
web.config can be at least partially edited using a new UI in IIS manager.
The only compilation errors I got were from Math.Floor and Math.Ceiling.
The compiler could not decide whether the input parameter was a decimal
or a double with lines like this:
Math.Floor(a/3-1); in which a
is an integer so it seems the methods are now more overloaded or the
type handling of numbers has changes since this was fixed with return
Math.Floor(a/3m-1m); (in which the m in 1m denotes a decimal value).
More experiences with .NET Framework 2.0 definitely coming up at some point - these were the results of the first hour of playing around or so.