There are, confusingly, two basic types of Visual Studio projects for developing web apps with ASP.NET: Web Sites (File –> New –> Web Site), and Web Applications (File –> New –> Project –> Web Application). I recently converted a legacy Web Site to a Web Application (and actually, to an ASP.NET MVC Web Application – there’ll be more on the conversion to the MVC framework in the next post), and ran up against several differences between the two during the process. First, a little history…
Visual Studio .NET 2002 and 2003 both shipped with versions of ASP.NET projects that were of the Web Application variety: ASP.NET web apps were housed in Visual Studio projects similar to other project types (such as Windows Forms apps or class libraries). Upon each change, the project had to be rebuilt for the resulting web application to reflect changes. This was an unnatural model for web developers used to simple HTML or dynamic languages such as PHP and Perl (where you have a running site, make a change to some code, then simply refresh a page and have changes appear).
In Visual Studio 2005, a new default type of ASP.NET project called Web Sites was introduced. This, through behind the scenes magic, allowed ASP.NET web apps to be created that were simply loose directories with code and aspx files (there was no Visual Studio project file that everything had to be associated with) that could be loosely edited and would be compiled at first page hit and dynamically refreshed as changes were made to the running web site. This followed a seemingly more natural model for web development, but got further away from normal model of application development with Visual Studio. There was some backlash from the community, and an add-on was later released for VS 2005 that allowed developers to use the older Web Application project type.
When Visual Studio 2008 was released, it supported both the Web Site and Web Application models out of the box, developers being able to choose the style they preferred (although I doubt if this choice was a clear one for most developers).
Until recently, both of these project types used the ASP.NET WebForms model. However, with the recent 1.0 release of the ASP.NET MVC Framework, there is yet another way to do ASP.NET (although, basically, MVC projects are Web Application projects).
Why did I do the conversion? Because, for my specific case, the features of the Web Application model better suited my project than those of the Web Site model.
Here is a list of the major differences I came up against:
- Web Applications can properly use conditional compilation constants (having them change based on build configurations).
- References are more tightly controlled with Web Applications (like normal VS projects). With web sites, it's a little indirect. Assemblies can be added to the Bin folder where they're automatically referenced by the site, or they can be referenced in the web.config file (for assemblies stored globally on a computer in the GAC).
- Since Web Application project files are proper MSBuild files, build actions can be done (pre- and post-build, etc).
- With Web Applications, namespaces can be more properly managed. With Web Sites, all compiled class code (not code behind files directly paired with a page), must be stored in a special "App_Code" folder. So, following the convention of storing classes in folders corresponding to their namespaces, these would have to be under an "App_Code.Blah..." namespace).
- Pages in web applications must have a "designer" file associated with them (e.g. “MyPage.aspx.designer.cs” for a C# web app). This is a partial class where the server controls in ASP.NET markup are declared in auto-generated code (all ASP server controls correspond to .NET objects). Here are Scott Guthrie's comments from his good walk-through (Rick Strahl also has a good description here and a re-visit to it here):
- “One difference between a VS 2005 Web Site Project and a VS 2005 Web Application Project is that the VS 2005 Web Site Project Model dynamically generates the tool-generated partial class half of a page, and does not persist it on disk. The VS 2005 Web Application Project model on the other-hand does save this partial class on disk within files that have a .designer.cs extension and compiles it using the in-memory VS compilers when a build occurs (one benefit of this is faster build times).“
- A strongly-typed profile object is automatically generated with the Web Site project type, but requires a special add-in to Visual Studio when using web applications (available here) for some reason. Alternatively, you can not use the strongly typed object and get values dynamically at runtime with magic strings.
- Web Site project "CodeFile" directives are "CodeBehind" in Web Application projects. These directives control how aspx pages are compiled. The CodeFile directive can still be used in Web Application projects, but are not compiled correctly. There’s a great tip in the comments on this post about possible confusion that can result when converting from a Web Site to Web Application project. Here's an excerpt from the comment:
- “The issue with CodeFile is that the code is compiled into its own (or directory level assembly) and so the type may not be available to another page unless the control is @Registered. If you dynamically load you pretty much can't reference the ASCX codebehind class. With WAP everything goes into a single assembly so you can reference the codebehind class from just about anywhere... The thing is that if you forget to set the proper format for WAP code the page/control will still work because ASP.NET internally doesn't care whether a project is stock or WAP so the page/control runs just fine with CodeFile.”
- Web Applications have a strongly-typed app settings section in the web.config corresponding (and automatically updating with code-gen) to the Visual Studio Project settings.
- When you compile a Web Application, it compiles the code behind files so that if a change is made to a running web app's code behind file it must be re-compiled (however, if you make a change to the aspx file of even a Web Application, then it still auto updates with an explicit re-compile – honestly, I'm confused about this part). With a Web Site, however, it will detect the change and re-compile no matter what.
- You must recompile a Web Application almost each time you make changes to it. This sounds worse than it is. The build is generally fast for me, as Visual Studio does a good job of keeping track of what has already been built and what really needs to be rebuilt. Also, you can "build" a Web Site project type from within Visual Studio, but really this is only doing a dry run of the build to catch possible compilation errors in the manner that the ASP.NET runtime does when a Web Site is visited.