Now that ASP.NET 2.0 and Visual Studio 2005 have been out for a few months and many of us have had some time to use the product in a day to day environment, it's interesting to take stock of the changes and how they affect the development environment and flow. To me personally ASP.NET 2.0 and Visual Studio 2005 have been a bit of a love/hate relationship.
There are many new features in ASP.NET 2.0 that just make life a lot easier and make it hard go back to 1.1 for coding. In my own work I've decided to move up most of my internal applications to 2.0 and not look back. So far it has worked out great. There are many improvements that have reduced code, improved performance and reduced memory footprint, even with almost no changes at all. Moving to embrace more of the 2.0 feature set in existing applications is not something that will happen overnight, but I am finding myself rapidly including many 2.0 features into my applications. In the end, going back to ASP.NET 1.1 and VS 2003 would seem like a huge step backwards.
Some of the key features that I find most useful and hard to do without are:
File based Projects in Visual Studio 2005 for development
In VS2005 you can now open a directory as a Web Project which is very nice. On my development machine I probably have 50 different Web projects hanging around and configuring and maintaining all of these as virtual directories in IIS and keeping the project references right as you had to in VS2003 is a pain. Don't think so? Have you ever tried to move projects to a new machine? So in VS2005 you point at a directory and the project opens. You can use he built in local Web Server to run the application which eliminates the need to configure a Web Server in any way. This feature is also great for developers who share examples – anybody who wants to check out a sample Web application doesn't have to go through the pain of configuring virtuals on IIS. Instead you now have – at least for development scenarios the true promise of xCopy projects. This is a great feature – but not one that comes without pain (more on this later).
The ability to define a master page template and reuse this master template easily throughout your application is a huge timesaver. There were ASP.NET 1.x based implementations of this concept floating around before 2.0 shipped, but to me the key feature that makes this viable is the visual support for it in Visual Studio, so that you can see the master layout along with the ContentPlaceholders used in each page to provide the page level content. In addition to the important visual aspect of the designer, Master Pages are also great to hook related and reusable code to the master template. Because Master Pages tend to wrap a fair amount of functionality that often required several user controls (for example, Header, Footer, Sidebar) Master Pages can isolate logic more completely than you could before.
Visual Representation of User Controls
Call me vain, but I really prefer to see what the whole page looks like while I'm designing it. Like Master Pages Visual Studio 2005 can now display a rendered User Control in place in the Web Form Editor. No longer do you have a non-descript grey box with a control name, but you now have a fully rendered layout right there in the designer. Double-click and VS takes you to the User Control designer. Although I don't use a lot of user controls, I find that this makes design mode a lot more useful especially for my existing 1.1 applications which generally used User Controls for headers, sidebars and footers. I foresee many of my existing user controls to be replaced by Master Pages.
Ok, this isn't an ASP.NET specific feature, but Generics in .NET 2.0 has had a profound effect on the code that I write. In the past, I'd been very wary of creating custom collections because frankly it was a pain in the butt having to subclass from CollectionBase and reimplement the same code over and over again. In ASP.NET especially I find that generic collections work really well for custom control development when you need collection properties. Use List or one of the specialized generic collections as a property of the control and you're done. Visual Studio sees the collection and provides the collection editor for you in most cases. Using Generic Lists also let me easily remove many ArrayList based lists as strongly typed lists which makes code cleaner in many places. Finally using dynamic type replacement in business objects removes a fair amount of funky initialization code that had to be specified in each object to define which type to work with for entity objects. All that configuration code could be replaced simply by making the type generic and assigning a single generic parameter to the class. All class level code can now generically use that generic class description to automatically generate the correct types at runtime. This has removed a huge chunk of traditionally cut and past code from all of my business objects and replaced it with one type parameter and a couple of class level methods. There are many more places where Generics have had a similar effect on my code and I find it hard to go back to not use Generic types and especially collections.
Support for embedded Resources
I tend to build a lot of custom controls for my own applications and occasionally for tools and demos I put out. If you build controls that require dependent resources such as images, CSS files, XML Resources maybe, it's a pain to have consumers of the control remember to distribute the appropriate files with their applications. Web Resources in ASP.NET allow you to easily embed and then access resources from within a project as a dynamic URL that ASP.NET generates. You simply add [WebResource] attribute to your control's AssemblyInfo file and then use Page.ClientScript.GetWebResourceUrl to retrieve the URL that contains the resource content.
The Visual Studio ASP.NET Code Editor
The code editor in Visual Studio is a huge step up from the 2003 version. Most importantly is that the new editor doesn't wreck your code formatting unless you reformat the document. In VS2003 this was a huge issue for me where I tried to keep my content organized and VS would gleefully step on it and reformat the HTML for me when new controls were added. Now in VS2005, the editor keeps the code intact for most things and also does a much better job with the default insertions of control markup into the code. Another big feature that enhances my productivity is Intellisense in the HTML editor – it's everywhere! I tend to embed <%= %>expressions into the page frequently and having Intellisense in place is very handy to avoid typos. ASP.NET also compiles the page and checks the embedded script code generated now, so that errors in the HTML markup can be caught at design time rather than runtime. Intellisense also works for all controls including your own. No longer do you have to provide an undocumented schema file. Visual Studio will simply find your control and internally manage the Intellisense. The Intellisense support is good enough that it almost makes sense to skip the visual designer altogether and work in code. You'll see why this is actually more important then you might think in a minute.
Truth is I could go on and on about features in ASP.NET 2.0 and VS 2005 that I use frequently now. Suffice it to say there are many useful and productivity enhancing features in VS2005 that make it a very hard call to have to go back to ASP.NET 1.1 and VS2003. Add to that a 10-20% performance gain without any changes from 1.1 at all, smaller memory footprint which are also real important to larger applications.
But there are also a number of issues with ASP.NET 2.0 and more specifically Visual Studio 2005 that don't sit well with me. It seems that while the ASP.NET 2.0 engine is very stable, tuned and performing well, Visual Studio doesn't fare nearly as well.
Visual Studio 2005 is Slow, slow, slow – especially for ASP.NET applications
I used to think that Visual Studio 2003 wasn't exactly a speed demon when it came to bringing up projects and switching views between documents, especially on Web Forms switching between code, HTML and Design views. In VS 2005, the performance of the editing environment especially for context switches between code and the designer is considerably slower. So much so that when I go back to VS2003 I'm amazed at just how fast it is. The main issue seems to be the Web Form editor which is dreadfully slow rendering controls onto the form. I have several large forms with about 50-70 controls on them and these forms take upwards of 15 seconds to load – for every context switch. I recently bought a new dual core laptop and while everything on my machine runs blazing fast, Visual Studio 2005 is the one application I can say is still not even close to as responsive as I would like. If you are upgrading, make sure you have a fast machine and LOTS OF memory. Running Visual Studio commonly results in nearly 500 megs of memory usage on my machine for Devenv.exe alone. Add to that either IIS's worker process or the VS Web Server plus browsers and you can easily chew through 2 gigs of memory.
Visual Studio 2005 Web Designer Bugs
The biggest time sink in VS2005 are a variety of editor bugs I and many others have found. Most of these are non-critical but they are highly annoying and waste lots of time. Here are a few of the more annoying examples:
The most frequent bug I run into is where the visual designer refuses to switch focus to another control. You click on a new control, but the property sheet stays locked on the first control. You have switch into HTML view, then back to get it to work.
In some instances when you try to rename the name of a control VS won't let you. It says there are already references in the mark up and do you want to continue. If you continue or not, the rename doesn't take and you have to switch to HTML view to change the name. Even when renames from the Web designer do work, they are very, very slow in a large project as VS is doing a full refactoring on the new name – it can take 10-20 seconds plus a dialog click for the rename to complete. Now keep in mind we're changing the name of a PROTECTED control attached to a Web Page here. Why is VS searching through whole project/solution??? I think it's safe to assume that a name change to a designer Page control isn't going to have much effect outside of the current page scope. Talk about the 99% scenario getting the shaft so that the 1% scenario (subclassed page used elsewhere) can work reliably. Besides if you change the control name in HTML view there are no checks at all – I would expect the Web designer to behave the same.
Another annoying one is using stock collections and the default Collection Editor. If you rename the default item names to a custom name, VS2005 simply doesn't save the changes. Simple blows away the properties and items you've entered. You have to use the default names or change the names in HTML view, then you can edit with the Collection Editor.
If you have style sheet references in the page VS.NET doubles up the style references randomly. I recently opened a page that had 10 of the same CSS references in the file and only one of them that I added.
Another issue that's not a bug but an odd implementation of a feature: VS.NET 2005 flags HTML validation errors as Errors. Validation errors are grouped in the same error list as a break-the-build errors. Not only is the HTML validation overly anal with what it flags (example: it doesn't understand named colors), but it gets in the way of seeing 'real' application errors. It's not uncommon for me to have 20-30 HTML 'errors' and 1 code error. The code error will be at the bottom where it's the least useful and there's no visual separation. Validation is useful, but it needs to be separate and easily toggled on and off, ideally with a separate error tab. Instead you can turn it on and off buried in the slow Options dialog – it's all or nothing.
The list could go on and on with these small but time sapping little bugs. The end result is that I spend a lot more time in HTML view than I should. Luckily HTML view is a lot more useful in VS 2005 with Intellisense making it much easier to enter property settings in code. I tend to use the designer to drop my controls on the form and move them into place, then use HTML view for most of my property assignments – at this point it's simply more efficient to work this way. But it shouldn't have to be this way.
Page Compilation Changes
I mentioned earlier that the new Web Project model is nice for development. In order for that model to work ASP.NET has introduced some fairly radical changes in how Web applications are compiled and deployed. Specifically ASP.NET pages by default compile into a single assembly for each page in the project. This makes it possible to unload each page individually so you can re-run it after making a change, but it also means that each of these assemblies is dynamically generated and cannot be easily referenced from within your applications. In other words, it's very difficult to get a strongly typed reference to another Page or User Control in your application, because there's no known class name you can cast to.
This proves to be problematic if you have subclassed Page classes where one Page inherits from stock behavior of another based on an ASPX file. In ASP.NET 1.x this was easy – you simply referenced the first class with its namespace and classname. In 2.0 there's no namespace, the name of the class is dynamically generated and doesn't exist in the same assembly. The biggest problem of this behavior manifests for applications that rely on dynamically loaded user controls. It's nearly impossible to get a reference to a user control that is not explicitly referenced using <%@ Register %>. The Register tag forces the Page assembly to reference the related assembly for the control, but if you're dynamically loading a user control at runtime no Register directive may be in place. So while you can load the control with Control. LoadControl() there's no way to cast it to the control type.
There are a few workarounds, from creating base classes and interfaces that provide the published interface, but none of them do much good for existing applications. A highly visible example of this is DotNetNuke which heavily relies on user controls as well as .Text (which I use for my WebLog) both of which don't run in ASP.NET 2.0 out of the box.
Web Projects aren't real Projects
ASP.NET projects aren't real VS.NET projects – they're a custom project type that is based on the operating system file system by default. If you open an ASP.NET Web project it pulls in any and all files below that project folder. This means you really have no control over what gets pulled into your 'project'. One particularily disastrous example is my root Web site which sits ontop of a large number of virtuals. There are probably 50,000 files below the Web root. When I opened the root in VS.NET it pulled in all of that – images, XML files, doc files, utilities; everything. It took about 20 minutes to open that project…
File projects have no way of excluding anything. Any file in the tree becomes part of your project. Images, support files, Configuration utilities, documentation files – all of which have little to do with my project. The reason for this is that there really is no project. A few things like the path mapping etc are stored with the solution, but overall there's none of the typical project configuration available that you see in class projects.
ASP.NET 2.0 compiles projects using a new ASPNET_COMPILER utility which copies everything to a 'deployment' directory. So not only is your project huge, compiling it copies the entire project including images and support files to a new location. As you can imagine this process is very slow. Compiling a medium sized Web of about 50 ASPX pages takes a good 30-40 seconds on my dual core machine. Compare with a couple of seconds for the same project under VS2003. Granted the compilation is more complete and results in a deployment directory, but while developing 30-40 seconds is too long – so much so that I rarely compile my Web project. Most of the time I work on a page, test run it and move on, but rarely do I do a full compile. The compile cycle is too slow.
Any code outside of CodeBehind pages stored in the same path as the ASPX files need to reside in the APP_CODE folder. Everything in APP_CODE is compiled and can contain plain classes, controls. Be careful if you create backup files – for example, I often do things like copying Control1.cs to Controlbak.cs. Because both controls now exist in the same project with the same code and this causes a compilation error as you end up with duplicate classes.
All the project dialogs look different than the 'stock' projects in VS.NET. There's no stock AssemblyInfo file, no support Xml Comments or direct MSBUILD support for a Web project. There is no project. All the information about the application is stored based on the filesystem layout and a few Solution file settings.
One workaround for the massive file importing of file projects is to use IIS Web projects instead which requires explicitly adding files. This is a little closer to the old model and at least respects virtual directory boundaries.
To Microsoft's credit, they are aware of the project and compilation issues and have started to provide a new Web Application Projects add-in that is still in Beta. It provides VS 2003 style Web projects (with some enhancements for the 2.0 functionality including file base project access). This tool addresses most of the concerns I've raised here, but it's not quite ready for release yet.
Deployment of Web Applications
Deploying of ASP.NET applications got a whole lot more complicated with ASP.NET 2.0. You now have many, many options for deploying your applications many of which overlap, none of which are simple and none of which produce a repeatable install. The new ASPNET_COMPILER utility is used to compile projects into a deployment folder. Options exist to compile every page in a single assembly, group all pages into a single assembly per directory, but none of the options produce a single assembly to deploy. In fact, there are lots of files to deploy including stub files and assemblies for APP_CODE and Master Pages.
Microsoft apparently intended people to completely re-deploy applications every time an update is made. The compilation creates a deployment folder with a copy of the Web site. VS 2005 includes tools that let you upload the deployment folder to your Web site. But that's pretty unrealistic. Typically you need to adjust web.config and possible other configuration files and you certainly wouldn't want to redeploy all of the incidental files like images for every update. But you can't update a site by simply copying one file with this new model.
The simplest install is a source install which deploys exactly as you are developing, installing both ASPX and codebehind source code on the server. Both are compiled on the fly. This is easy to deploy and you don't actually need to run ASPNET_COMPILER, but it's not exactly secure and you have to track changes to all source files.
You can deploy compiled assemblies for each page, which create one assembly per page and are stored in the BIN directory. That would be OK, except every time ASPNET_COMPILER is run, the timestamp and file name changes, so the next time you upload you have to clean up the old compiled files. Options allow you to compile both ASPX and CS file or leave the ASPX file intact and let ASP.NET compile the ASPX page content at runtime.
You can also group directories together into a single assembly of all ASPX files in that directory. This produces fewer assemblies, but unfortunately there are marker files for every page which – you guessed it – change name on every compile. So the number of files is no less with this installation. In both cases additional assemblies are created for the APP_CODE directory, Master Pages and a few other separated files all of which are dynamically named.
The worst thing about this deployment is that there's no quick and dirty way to deploy with the stock options. You basically have to remove files on the server before you copy them back up. And while you're copying files to the server you application is a very unstable state as there are many files which can become out of sync while uploading. In short, live updates are not really possible on a busy site.
Microsoft has heard the message from developers a little late and has made an add-in tool available called Web Deployment Projects which is in Beta. This tool builds on top of the ASPNET_COMPILER functionality and can combine all the assemblies into a single assembly. Further it can create stub files that have a consistent name, so you can create a repeatable deployment image. The tool also allows custom build actions to modify Web.Config files easily for deployment on the fly. This add-in provides a new VS.NET project type and you can use MSBUILD to customize the process. I've been using the command line version of the tool for my deployment needs and it works much better than the stock behaviors. It makes the process much more manageable.
With all these choices available, I created a GUI front end to ASPNET_COMPILER and the Web Deployment Projects with a West Wind ASP.NET 2.0 Compiler Utility. The tool lets you experiment with the various different compilation modes, save the configuration, create batch files and more.
Will Microsoft do the right thing?
There are a number of things that bug me about ASP.NET 2.0 and Visual Studio 2005, but there are also many things that make life a lot easier for development. The productivity and feature gains and the slowness and bugs roughly offset each other in net productivity in my estimation. But with a little effort on Microsoft's part it could be so much better.
But it's not there yet. One look at the faces of developers I stand in front at presentations when you see some of the issues described above says it all – "this stuff looks like Beta software". It happens all the time. I can't tell you how many people have asked me whether they should upgrade to VS2005 and whether it's 'good enough'. I'd say yes it is, but don't expect a bug free environment in Visual Studio.
Microsoft is aware of the issues and I've seen many Microsoft developers get involved in Blogs and message boards to address these issues, so if and when a Service Release for VS.NET 2005 becomes available most of these issues should be resolved. I sincerely hope that Microsoft is making a strong commitment to fixing these and other issues and fixing them sooner rather than later. Microsoft has a tendency to move on to the next big thing and already we're hearing talk about the next version of Visual Studio.NET (Orcas). Let's hope that this release can still be made all that it was meant to be for so many years.
I'll be at DevIntersection in Vegas this fall giving sessions on ASP.NET Core with Angular and Localization. Thinking of coming? Use discount code STRAHL and save a few bucks. If you do be sure to stop by and say hello!
Other Posts you might also like