Site pre-compilation in ASP.NET 2.0

Onion Blog

Syndication

One of the more interesting compilation features coming in 2.0 of ASP.NET is the ability to pre-compile an entire application and deploy nothing but binary assemblies. Many people have requested the ability to do this in the past so that once an application is deployed you can rest assured that no one will change anything in your deployed application without going through your deployment process (or using dissassemblers and ilasm, in which case they probably deserve to change it :)
 
The way it works, is you run this new utility called aspnet_compiler.exe and point it to a virtual directory on your machine, also specifying a physical path where you would like it to dump out the binary compiled application ready for deployment.
 
For example, if you had a vdir on your local machine called myapp with an ASP.NET application, the following command would compile it and drop it into the c:\deploy directory:
 
aspnet_compiler -m /LM/W3SVC/1/ROOT/myapp c:\deploy
 
If you look at the output in the c:\deploy directory you will see all of the endpoints in your original application (*.aspx, *.asmx, etc.) but instead of containing the ASP.NET markup they used to have, they will be empty files containing only one line of text:
 
"This is a marker file generated by the precompilation tool, and should not be deleted!"
 
You will also see a text filed named PrecompiledApp.txt which contains the following line of text:
 
"This application has been precompiled by the aspnet_compiler.exe tool.
Please do not delete this file!"
 
and finally a /bin directory with a number of assemblies and .compiled files referencing types and which assembly they are stored in (using an XML format).
 
You can then deploy this directory to a server and there will be no request-time compilation, as all page types have been pre-compiled in the /bin directory. Interestingly, if you try and add a new .aspx file to this precompiled site and navigate to it, you will find that it generates an exception stating that the file is not precompiled and this application serves only precompiled content. Very slick - so no one can even add new .aspx files to your deployed application.
 
I was curious how they implemented this, so I dug through some System.Web.Compilation classes with Reflector and found the following property in the BuildManager class:
 
private bool IsPrecompiledAppInternal
{
      get
      {
            if (!this._isPrecompiledAppComputed)
            {
                  string text1 = Path.Combine(HttpRuntime.AppDomainAppPathInternal"PrecompiledApp.txt");
                  this._isPrecompiledApp = File.Exists(text1);
                  this._isPrecompiledAppComputed = true;
            }
            return this._isPrecompiledApp;
      }
}
 
 
The check to see whether the BuildManager is dealing with a precompiled application or not is simply a check for the presence of a file named "PrecompiledApp.txt"! (Note this is in the Beta1 Refresh and may be subject to change in the release). Just to verify that this was true, I went ahead and deleted this file (in spite of it's sincere pleading for me to not do exactly that :) and tried to access my non-precompiled .aspx file again. It failed! But the reason it failed was the _isPrecompiledAppComputed flag was set and it is not flushed when the directory changes. So I then bounced the worker process and tried again, and voila - it compiled and rendered the page no problem. In fact, if I then navigated to any of my previous .aspx pages they just rendered the 'marker file' text inside of them.
 
Note that the opposite is also true, you can drop a file named "PrecompiledApp.txt" into any ASP.NET 2.0 application directory and the BuildManager will serve up only pre-compiled types (meaning all .aspx pages will fail to compile and nothing will work, bwa ha ha :) If you're looking for a good April Fool's day trick to play on a colleague ... I've said enough already.
 
I should also note that the .aspx endpoints do not even have to be present in the deployed pre-compiled application, unless you have checked the 'verify that file exists' checkbox in IIS for the virtual directory. You can truly deploy only a /bin directory and one innocuous text file (PrecompiledApp.txt) to a server with no .aspx files whatsoever and it works fine.

Posted Nov 11 2004, 08:17 AM by fritz-onion
Filed under:

Comments

GuyIncognito wrote re: Site pre-compilation in ASP.NET 2.0
on 11-11-2004 9:24 AM
Wow, this is way cool!
Sergio Pereira wrote re: Site pre-compilation in ASP.NET 2.0
on 11-11-2004 10:09 AM
And if you arrange your static files (.htm, ,js, .gif, etc) as WebResources, then you won't need even those.
Kevin Cunningham's Blog wrote ASP.NET Precompiled apps
on 11-11-2004 8:53 PM
Kevin Cunningham's Blog wrote Some ASP.NET 2.0 Precompiled app details
on 11-12-2004 6:23 AM
Tim Haines wrote ASP.NET Precompile
on 12-13-2004 9:43 PM
Tim Haines wrote ASP.NET Precompile
on 01-02-2005 11:46 AM
sujay wrote re: Site pre-compilation in ASP.NET 2.0
on 01-18-2005 1:41 AM
how to generate a single dll in whidbey
TrackBack wrote the rasx() context » Links: .NET Links to .NET Stuff
on 04-13-2005 12:09 PM
the rasx() context » Links: .NET Links to .NET Stuff
Rick Strahl wrote re: Site pre-compilation in ASP.NET 2.0
on 05-13-2005 12:56 AM
It kinda sucks that this is an all or nothing approach. If you have a large Web Site with a lot of images this mode of deployment is going to be a problem. If you have a site that contains just a few ASPX pages within a bigger site that may have thousands of pages the only alternative will be to deploy with source code.

It seems there's no clean way to compile just the codebehind pages as you could in 1.1 and deploy just that. This is one feature I really do miss in VS.NET 2005. OTOH, this is really no longer possible with the new code model since the partial that is used as a part of the base class (control declarations + our Page code) must be generated from the ASPX file.

In some ways the old way of deploying seemed a lot simpler where it was pretty easy to tell what needs to go up to the server.
Some Random Dude wrote re: Site pre-compilation in ASP.NET 2.0
on 06-15-2005 12:06 PM
Umm, this isn't an all or nothing approach, it's in addition to what we already have. You can still deploy sites the exact same way you do with 1.1.
Rick Strahl wrote re: Site pre-compilation in ASP.NET 2.0
on 08-15-2005 11:59 PM
No you can't. You can't deploy single assemblies for your app because it's not available. You can't deploy ASPX files directly out of your development directory because the ASPX files need to be modified (removing the codefile attribute which the precompiler handles). You can't just copy files to the server without deleting the old BIN directory files because you get duplicate assemblies. Most importantly unless you want to distribute your CS files on the server you can't deploy without using the pre-compiler!

That's a lot of "Can't's" if you ask me...
Rick Strahl wrote re: Site pre-compilation in ASP.NET 2.0
on 08-16-2005 12:01 AM
Ooops. I meant you get duplicate classnames in the assemblies... (and this goes for updateable compiles only, which is the only way to get a compile that has a reasonable number of files you need to copy to the server).
Muralidhar A.H wrote re: Site pre-compilation in ASP.NET 2.0
on 04-03-2006 6:47 PM
This is a good solution. Please tell me how to remove the precomilation settings for a project.
Angry user wrote re: Site pre-compilation in ASP.NET 2.0
on 05-20-2006 10:53 AM
First time since .NET start when I'm thinking to switch to Java...
The recent launch of "Web Application Project" prooves they realised what a huge mistake was to add unnatural features to VS
"EVERYTHING BASED ON XCOPY WILL LAST FOREVER"
anonymous email wrote re: Site pre-compilation in ASP.NET 2.0
on 07-13-2006 11:29 PM
Thank for the info. Is there a little tool which does all the pre-compilation. I am not used to the ms-dos promt.
John wrote re: Site pre-compilation in ASP.NET 2.0
on 06-28-2007 1:02 PM
I have built a site using Visual Web Developer Express and precompiled it with ASP_Compiler. After uploading the ASP_compiler output files to the production server I get the following message when I go to the site address:

This is a marker file generated by the precompilation tool, and should not be deleted!

Can someone please tell me how to fix this? I don't know very much at all and would appreciate "idiot" level info, ie step-by-step. Many thanks in anticipation.

NB I do not have IIS, am running win 2k and don't have the op system CD since my computer is 2nd hand.



Samson wrote re: Site pre-compilation in ASP.NET 2.0
on 07-24-2007 5:07 PM
Thank you. I was looking for this!!!
Mike L wrote re: Site pre-compilation in ASP.NET 2.0
on 01-22-2008 9:10 AM
I'm not sure Rick Strahl is correct. I'm using VB not CS, but if you use the Fixed Names option, you should be able to copy individual page assmemblies to the production server. In VS2005, use the Publish Web Site option under the Build menu and publish to a local folder before copying files to the production server. Choose the option "Use fixed names and single page assemblies." If you uncheck the option "Allow the precomplied site to be updatable", then the whole page will be compiled including the UI, and then all you need to copy if a page has changed is the .dll and the .compiled files. However, if a user has a session open, the session will be terminated. That's the problem I'm looking into next.
Jeremy wrote re: Site pre-compilation in ASP.NET 2.0
on 04-02-2008 11:51 AM
I am not a big fan of the precompile too; more trouble than good!

Add a Comment

(required)  
(optional)
(required)  
Remember Me?