OdeToCode IC Logo

More on Conditional Compilation in ASP.NET

Tuesday, September 25, 2007

Phil dug up an old post of mine on conditional compilation, but defining a constant in web.config didn't appear to work for him. I didn't see anything wrong with his approach, so I downloaded the solution and did some spelunking.

With this page ...

<%@ Page Language="C#" 
    
CompilerOptions="/d:QUUX" %>
...
    <div>
       <% #if BAZ %>
         BAZ in the aspx file.
      <%
#endif %>
      <%
#if QUUX %>
         QUUX in the aspx file.
      <%
#endif %>
    
</div>
...

... and this web.config ...

<system.codedom>
   <
compilers>
      <
compiler
         language="c#;cs;CSharp" extension=".cs"
         compilerOptions="/d:BAZ"
         type="Microsoft.CSharp.CSharpCodeProvider, System,
             Version=2.0.0.0, Culture=neutral,
             PublicKeyToken=b77a5c561934e089
" />
   </
compilers>
</
system.codedom>

... then the page behaves as if only the QUUX is defined.

To understand the scenario I added <compilation debug="true"> to the web.config. Debug settings leave behind a .cmdline file in the temporary ASP.NET files directory. The .cmdline file contains the exact commands to invoke the C# compiler, and the abbreviated form looked like this:

...
/t:library /utf8output
/D:DEBUG /debug+ /optimize- /nowarn:1659;1699
/d:QUUX  
...

I went in thinking the compilerOptions would be additive, but after a smack on the forehead, I realized the compiler options in the @ Page directive override the web.config compiler options. Remove the compilerOptions attribute from the @ Page directive and BAZ becomes defined.

The behavior does seem to follow the principle of least surprise, even if it did catch us off guard.