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.
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.
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".
I did a recent blog post about this
if you are interested in a more polished explanation.