Friday, May 30, 2008

Web Site vs. Web Application Project

In Visual Studio 2005 and later, there are some significant differences between a "web site" and a "web application project" (WAP).

Project structure
A web site has no project file. The "site" is simply the collection of files in the site's directory. Project/binary references and other configuration settings are stored in the web.config file (poor form in my opinion).

A web application project does have a project file, it's treated as a class library project. However, the visual studio template for a WAP provides some additional things such as what types of items are visible in the "Add new item" dialog (i.e. web form, master page, user control, web.config, etc) and configuration of debugging such as the settings for the development web server or IIS.

Codebehind/Codefile attribute
In a WAP, the markup directive (@Page, @Control, etc.) contains the "Codebehind" attribute. This is actually meaningless to the ASP.NET runtime, it's a linking attribute used by visual studio to indicate what the code-behind file is for the markup file.
In a site, the "Codefile" attribute is used. This is similar to the "Src" attribute. (I've experimented with the two and can't find a significant difference between them.) It tells the ASP.NET runtime what source code file should be compiled together with the markup. This is what links a markup file to a code behind file in the dynamic architecture of web sites.

Compilation
In both a site and WAP, the markup (AS?X files) are dynamically compiled. There is an exception but it's an advanced topic. All code files (including page code-behind) for a WAP are always pre-compiled. In a site, nothing is pre compiled. The ASP.NET runtime will compile everything in the App_Code directory into one DLL and each page will get compiled into its own DLL. This affects the class scope.

Class scope
Only code in App_Code is available to all classes in a site (that's where you HAVE to put shared code). In the WAP - because it's pre-compiled - all page classes live together in the same assembly and can thus see each other.

Namespaces
Perhaps the largest difference between the two is with the namespaces are constructed.
In a WAP all classes are created by default as members of the root namespace defined in the project (typically the project name). For example, in a project named "MyProject" the new page "MyPage" will have a fully qualified class name of "MyProject.MyPage". When you create sub directories in the project, visual studio creates another namespace level for pages created in those directories by default. So if I create a folder "Admin" and another page "MyPage" I will get a class name of "MyProject.Admin.MyPage".

In a site, all pages are part of the default root namespace for dynamically compiled pages: "ASP". Class names are created with underscore separation of their location when they live in sub directories. In a web site, instead of "MyProject.Admin.MyPage" the page class would actually be "Admin_MyPage". When it's dynamically compiled it will become "ASP.Admin_MyPage".

Which to chose
It is important to chose the right project type. With the changes introduced in Visual Studio 2005, it is now much easier to work with either type of project (no more IIS integration, woohoo!). Being able to open a web site via FTP is very helpful for certain needs. For some, the web site model will be ample. It's great for tests or simple sites that aren't code intensive.

However, I have found that in professional development the WAP is the better choice. Because there is a project file "controlling" the project it's easier to manage it with regards to what is actually included in the project which helps to control things such as the source control repository items for the project. In my case, having the project file is also necessary for the build system as the project file provides the parameters for what to build for a given project.

Yes, using a WAP forces us to always precompile the application. On the down side, this makes updates more difficult because any other changes are rolled in with it, we can't just update one single page. However, this is good in several ways.

Simply put, production code should not be updated willy-nilly. We need to exercise a fair amount of control over what gets pushed to production. The app should be regression tested by QA. Also, with a good build system and source control practices, you can do updates as necessary to deploy patches without including changes being made in a given applications main trunk. If you do need to make a change, there are ways to "patch" a single page by reverting it to the web site code file model.

Another benefit of using the WAP is that the project configuration is kept in the project file instead of in the web.config, where it really doesn't belong. This keeps the concerns (configuration of the actual app versus configuration of the project within Visual Studio) well separated.

Yet another good aspect to the WAP is that you can "see" all the classes in the project - they are all within the scope of the entire assembly. In some large projects with many developers and many pages that require query string arguments to function I've used a technique for doing "strongly typed page urls". Follow the link for more details, but in short: I create static page methods that return a properly formed URL. Using a managed method provides the opportunity to force required page parameters by using regular method arguments.

This is all obviously very biased towards using the WAP. This is partially due to where ASP.NET development started, in 1.1, with the web project. In the interest of full disclosure, I haven't worked with the web site model enough to really speak fairly for it. However, between the little I've worked with it and from what I've heard from speaking with other developers, for anything that isn't a trivial web site, the WAP is the way to go. The web site type is good in some cases, but as with any tool, it should be used where appropriate. Fortunately, Visual Studio has pretty good support for converting a web site to a web application project, so starting upgrading from a site is not terribly difficult.

12 comments:

SeniorNet said...

Hi,

I have been a .Net developer since it's inception (I was C++ developer prior to than). I have worked a lot more on WAP than website projects. I must say for many applications, WAP makes more sense; however, I have worked for small ASP companies; in these cases, website projects work a lot better than WAP because changes can be made quicker. In case of an urgent push, it is a lot easier to make the push as a website project. I know many people are fans of WAP (I was one of them); nevertheless, I am pragmatic and I have found out that when you maintain a site; it is more convenient to use a website project.

Isaac said...

A Web app is needed if you want to use nunit for unit tests. With a website that's pretty difficult (impossible?). Likewise all the other open source unit test tools can be used with a web app and you can then use NAnt and CruiseControl too. The .dll files have meaningful names and you can include references for for test code. A web app is a tiny bit more work; but crucially important if you must write unit tests.

There seems to be no way to convert from a website to a web app.

Felipe Lima said...

Great post, thanks for sharing!
I've been working almost only with website projects and that worked fine for small/quick websites. WAP seems a bit more work, but I suppose you perhaps get more speed during runtime due to less code to compile.
I also found it hard with WAP to just copy/paste already existing aspx pages from other projects, since they wouldn't compile at first try. Besides that, if you paste some code to an aspx page with some server controls, they won't be available in the code-behind, unless you manually declare them in the somepage.designer.cs file.
These were my first impressions about the WAP project type. Please let me know if my findings are wrong!

Cheers,
Felipe

Stuart said...

Thanks a lot for putting the time into this - it's just what I was looking for.

madeinstein said...

How do you work with designers when you use WAP assuming they use one of the microsoft expression products like Expression Web?

jvoss said...

Thank you for posting this. I'm relatively new to .NET and recently took on a project that was developed as a WAP. I had only worked with sites before that, and this has explained some of the things I couldn't understand.

Mehak said...

It was a good read. I have worked with both WAP and website projects. But now I have to convert one WAP to Website. Any idea where I can get information regarding this migration?

DaveHetesi said...

I find that the WAP is way too time consuming. Having to stop and start the debugger to make changes takes up too much time. We develop sites with hundreds of pages and the compilation time of the WAP is too long. The web site project allows changes to be made much faster.

And just so everyone knows, the website project DOES have a project file. When you open a website in VS a project file is created in your documents folder. You can copy this file anywhere and use it like a regular project file.

Anonymous said...

I think it really depends on client needs also. I recently lead a website project consisting of over 6000 pages for a client. Each page having dynamic and static regions. This client has it's own webteam who need to be able to make small changes many, many times a day. In this scenario, a WAP does not make sense. There is also no performance gain, at all, when talking precompiled assemblies vs dynamically compiled dll created by the app_code folder. This has been verified by Scott Gu and makes perfect sense - your only performance gain is first request compilation, but for a site which gets 60,000 concurrent users, this is meaningless; The site never "cools down" so the dynamically compiled dll just stays up. We have a small core WAP setup for unit testing, but the deployed client site is a website project - so it's the reverse of what you are saying here, even for a massive scale project. In practise, flexibility can be very business critical.

Ali said...

Thanks for explaining the difference. I was happy to see support for the web site model in VS2008.

dotnettips said...

useful

tripsomee said...

Web Site does not create .designer files for each and every page. In a Web Site the Markup is interpreted as the design. Not having them in a 'Web Site' project type is a significant advantage over 'Web Applications' in my opinion and keeps thing simpler.