views:

688

answers:

4

I understand that Web Site Projects compile source on-the-fly, and Web Application Projects pre-compile source into a DLL (much like ASP.Net 1.x).

But how is the difference specified in IIS?

I know that Visual Studio knows -- there are different projects for each, etc. But the running instance (IIS + Framework) has to know which compilation model is being used, right? Because how else does it know whether or not to compile on-the-fly?

A request comes in, hits an ASPX file...and how does the process know whether the associated CS file needs to be compiled (Web Site), or if it was already done before deployment (Web Application)?

I'm just curious where this difference is specified. In the web.config somewhere?

A: 

I'm pretty sure the framework handles this and it is transparent to IIS.

Jimmie R. Houts
But how does the framework know? Somewhere, on the the production Web server, there has to be some setting or flag that says "compile this on-the-fly" or "don't, because it's all in that DLL over there."
Deane
A: 

Once the website or webapplication is compiled there is no difference for the webserver. The .NET handlers in IIS always:

  1. Compile the ASPX pages.
  2. Jit the constructed assemblies into the temporary files area.
  3. Run the request

In the scenarios where the site is compiled completely into a single dll there are either still single line ASPX files telling the .NET handlers in IIS where to get the code. Or the ASPX pages can be removed altogether with some extra configuration lines in the web.conig.

But the short answer is really once compiled they are identical.

David McEwing
I realize they're identical, but how does IIS (or the framework -- whatever) know that the .cs files in the Web root are already compiled into a DLL in the bin...or not?
Deane
It doesn't. The handler takes care it of it and it treats it the same every time. IF the code behind is specified in the aspx @Page directive then the handler will obviously need to complie that first. In VS there it is basically a symantic difference, but once it is deployed to IIS the aspnet_isapi filter treats them both the same.
David McEwing
+2  A: 

All IIS does is pass the incoming request to the appropriate handler. In the case of an ASP.NET site/application it is aspnet_isapi.dll. The handler then takes care of everything from there.

Colin Cochrane
You can view/edit/wreck this link in the IIS administrator: open the properties of a website or virtual directory, select the Home Directory tab, click the Configuration button (bottom right), Mappings tab.
Stijn Sanders
+8  A: 

There is a subtle difference in the .aspx file that you'll find in these project types.

If you look at a Web Site Project you should see something like this...

<%@ Page Language="C#" AutoEventWireup="true"  
CodeFile="Default.aspx.cs" Inherits="_Default" %>

... where as the Web Application project will have .aspx files with something like this...

<%@ Page Language="C#" AutoEventWireup="true" 
CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>

Notice that the first has a CodeFile attribute, and the second as a CodeBehind attribute. This is where the distinction is made.

The CodeBehind attribute is NOT used at runtime - it's there to tell VS.NET where the code lives, and the Inherits attribute tells the runtime which class to go searching for in the binaries.

The CodeFile attribute IS used at runtime, and is used by the aspnet_compiler.exe to generate code, and then the Inherits attribute is used as above.

For more info on these attributes, look here...

http://msdn.microsoft.com/en-us/library/ydy4x04a.aspx

But to answer your question "how does IIS know?" the answer is "it doesn't." ASP.NET knows.

You can prove that this is the case by doing the following:

  1. Create a new web application. This will include a Default.aspx and a Default.aspx.cs.
  2. Add the following code into Default.aspx.cs:

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("hello");
    }
    
  3. Compile the project, run it, see the text "hello" appear in a browser.

  4. Now, change the code so it looks like this, and save the .cs file:

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("goodbye");
    }
    
  5. DO NOT COMPILE. Refresh your browser. You'll still see "hello" because the compiled code still uses this string.

  6. Now, change the attrib in Default.aspx from CodeBehind to CodeFile. Save this file.

  7. Refresh your browser. You'll see "goodbye" displayed.

  8. Change "goodbye" in your code to "I believe!". Save the .aspx.cs but don't compile.

  9. Refresh your browser, see "I believe!", and dance around the room enlightend :-)

Martin Peck
Assuming this is accurate, it's *exactly* what I was looking for. I *knew* there had to be some little setting somewhere...
Deane
So, try it out. Take a web app project, change an .aspx file to have a CodeFile attrib instead of a CodeBehind attrib, and see if you can now edit the .cs on a live site and see differences without using VS.NET to compile the code. I just did this test and proved it to be true.
Martin Peck
I've edited my answer with some "how to try it out" steps.
Martin Peck
So, could some Web forms in the same site have CodeFile and others have CodeBehind? What would happen? (I have no idea why you would do this, but it's interesting to consider...)
Deane
Yes - you could mix and match. As you say, doing so would be a strange thing to do. In fact, I tend to think that the Web Site mechanism of having ASP.NET compile stuff at runtime is a poor idea - I like to have unit tested my code, FxCop'd it, and know it's good (rather than just throwing some .cs files onto a website and hoping for the best).
Martin Peck
thanks a million for this :)
Vuk
+1 - thanks - useful!
nonnb