As you might already know we have two different project types for web development in Visual Studio 1.) Web Application Projects (WAPs) 2.) Web Site Projects (WSPs)…
Often time developers hear that if you want to put a random class file in your web project you should put it in App_Code folder. While this is true for Web Site Projects (WSPs), it is not so much true for Web Application Projects (WAPs) and in this post I will try to explain the inner workings on why that is the case…
Firstly App_Code folder is a special ASP.NET RUNTIME folder… Any files in this folder are compiled by ASP.NET when your site is actually running on the server... This essentially allows you to drop random class/code files in this folder to be compiled on the server side… For this very reason if you drop something new into the App_Code folder of your running web site, it is like resetting it coz ASP.NET runtime now recognizes that there is a new class which needs to be kept in consideration during running the site… This magical folder brings with itself various connotations when it comes to different project types…
First of all it is important to know that Visual Studio does not really create any DLLs when you are using Web Site Projects (even when you are building the web site)… VS simply validates that your code is correct in WSP… In Web Application Projects (WAPs) this is not actually true as VS actually creates a DLL with all the code behind and class files that are present in your project and drops them into the BIN folder of your project…
In case of WAPs every file in the project is marked with a specific “Build Action” as shown below:
All the class files (.vb/.cs) are marked as “Compile”… This essentially tells VS to take all those files and call the correct VB/C# compilers on them… The result of that activity is the DLL,which is named same as your project name i.e. WebApplication1.dll, being created in the BIN folder of your project…
With this understanding let us look at right click Add—> Add ASP.NET Folder --> options on Web Application Project
You will notice that App_Code folder is not really available as an option… This is an intentional behavior…
If you add a App_Code folder into a Web Application Project and add classes to that folder then more than likely their “Build Action” will be marked as “Compile” (as all .vb/.cs files are defaulted to “Compile”)… This will signal Visual Studio to compile them inside the IDE to produce the DLL in the BIN folder… For illustration let us assume you added a class called Products in App_Code\Products.cs file which is marked as “Compile”… Now when you build your WAP you will get a DLL in your project BIN (e.g. WebApplication1.dll), which when you open in ILDASM or Reflector will tell you that Product class exists in it…
Now when you try to run the project locally or do a xCopy deployment of your WAP to the server you will might accidentally move the App_Code\Products.cs on the server as well… This is time when things start getting tricky… Now you have a DLL in the BIN which is provided as a reference to ASP.NET runtime which has the Products class… Also ASP.NET is trying to compile your App_Code folder (as it is a special Runtime folder and that is an expected behavior) which will result in duplicate declaration of your Product class (one in the referenced project DLL and second in the dynamic compilation)… As you can imagine duplicate declaration of same type is not desirable…:-)
Additionally, VS will auto generate namespace for your Products class in the DLL to be something like WebApplication1.App_Code.Products vs ASP.NET runtime will produce a hashed version of the name space causing additional connotations giving you weird error messages…
So at a high level there are many reasons why App_Code folder is not supported for Web Application Projects and should be avoided…
Does this mean App_Code and WAPs just don’t ever work together?
No, that is not true… App_Code and WAPs can work together, you need to make sure that “Build Action” of none of the files in the App_Code folder is marked as “Compile”… Ideally you should mark them as “Content” which will ensure that they will get deployed on the destination and get compiled by ASP.NET instead of locally by VS IDE…
But this will bring its own side effects that intellisense may not work very well for these files inside VS as they will not be treated as Class files by VS… But the key point is that you do not really need “App_Code in Web Application Projects (WAP) if you do not intend to put random code files or modify existing code files in App_Code folder directly on your production server…
What should one do if there are isolated code files which need to be added to WAPs?
You can add code files under any folder call it “CodeFolder”, “Controllers” or anything that makes sense in your project… Just avoid putting them under “App_Code” unless you specifically want the server side compilation behavior…
-Vishal