Thursday, May 24, 2012

MVC3 Razor and Preprocessor Directives Deficiency

You may have used preprocessor directives in ASP.NET Webforms to conditionally include code segments in markup for in the code-behind files. I have used them in master pages and aspx pages to do things like conditionally including Google Analytics or include compressed versus verbose CSS and Javascript.

Example including Google Analytics when DEBUG is not defined.
<% #if !DEBUG %>
<script type="text/javascript" src="/scripts/ga.min.js"></script>
<% #endif %>

Example including verbose CSS versus minified CSS.
<% #if DEBUG %>
<link rel="stylesheet" href="/Styles/Default.css" type="text/css" />
<% #else %>
<link rel="stylesheet" href="/Styles/Default.min.css" type="text/css" />
<% #endif %>

If you are like me, you may have tried to use this technique in MVC3 Razor. But what you may not know is that MVC Razor views are always compiled in DEBUG mode! That's right, it does not respect the debug attribute on your compilation web.config element! This is a huge issue, and frankly I am surprised that this has not yet been fixed.

In trying to find answers, I found this response on this thread which confirms the issue.

There is hope though! We have a few ways that we can conditionally include code in our Razor views.

Use IsDebuggingEnabled

Instead of using preprocessor directives in Razor, you can instead use the following property to test if the web.config compilation element's debug property (Reference here: Stack Overflow).
HttpContext.Current.IsDebuggingEnabled

That property will check your compilation element's debug property in web.config.
<system.web><compilation debug="true">...</compilation></system.web>

Create a Static Extension Method that uses preprocessor directives

Shawn on Stack Overflow posted an example of an extension method that can be used in conjunction with preprocessor directives.
    public static bool IsDebug(this HtmlHelper htmlHelper)
    {
#if DEBUG
      return true;
#else
      return false;
#endif
    }

Then in your view, just check IsDebug().


IMHO, this issue should be addressed in MVC4. There is no reason for the code bloat that Razor causes by not respecting the DEBUG compilation flag. If anyone can find the Microsoft connect issue, please comment and I'll add in my 2 cents!

Links

1 comment: