mamu
mamu

Reputation: 12414

Preprocessor directives in Razor

I am writing my first Razor page today, and can't figure out how to enter

#if debug
...
#else
...
#endif

How can I do that in Razor?

Upvotes: 269

Views: 86336

Answers (11)

Mustafa şentürk
Mustafa şentürk

Reputation: 41

The simplest solution as far as I know is this:

@{
#if DEBUG
}
<div id="blazor-error-ui">
   <environment include="Staging,Production">
    An error has occurred. This application may no longer respond until reloaded.
   </environment>
   <environment include="Development">
    An unhandled exception has occurred. See browser dev tools for details.
   </environment>
   <a href="" class="reload">Reload</a>
   <a class="dismiss">🗙</a>
</div>
@{
#endif
}

Upvotes: 2

Mr Moose
Mr Moose

Reputation: 6344

I needed something similar that works in the <script> tag as well, and found that the following works well for either conditional markup in the DOM, or a conditional script.

@{
#if NOEXTAUTH
{
    @:<!-- A single line of code -->

    <text>
        <!--
        A multi-line block    
        -->
    </text>
}
#endif
}

Upvotes: 3

Perry Armstrong
Perry Armstrong

Reputation: 171

This works for me in a .NET Core 3.0 white label project:

@{
#if CORPA
}
    <button type="button" class="btn btn-warning">A Button</button>
@{
#else
}
    <p>Nothing to see here</p>
@{
#endif
}

Upvotes: 17

beleester
beleester

Reputation: 454

In .NET Core, you can use the environment tag helper instead of checking the preprocessor variables:

<environment include="Development">
    <!--Debug code here-->
</environment>

Upvotes: 29

Jordan Gray
Jordan Gray

Reputation: 16499

This is built in to HttpContext:

@if (HttpContext.Current.IsDebuggingEnabled)
{
    // Means that debug="true" in Web.config
}

IMO, this makes more sense than conditional compilation for views and comes in handy for some testing scenarios. (See Tony Wall's comment below.)


Side note: NullReferenceException for HttpContext.Current

Alex Angas mentioned that they get a NullReferenceException with this solution, and a few people have upvoted indicating that this may not be an isolated event.

My best guess: HttpContext.Current is stored in CallContext, meaning it is only accessible by the thread that handles the incoming HTTP request. If your views are being rendered on a different thread (perhaps some solutions for precompiled views?) you would get a null value for HttpContext.Current.

If you get this error, please let me know in the comments and mention if you are using precompiled views or anything special set up that could result in your views being partially rendered/executed on another thread!

Upvotes: 331

tedebus
tedebus

Reputation: 1050

My solution is very stupid, but it works. Define a global constant somewhere in a static file:

public static class AppConstants
{
#if DEBUG
        public const bool IS_DEBUG = true;
#else
        public const bool IS_DEBUG = false;
#endif
}

Then use it with Razor in HTML:

@if (AppConstants.IS_DEBUG)
{
    <h3>Debug mode</h3>
}
else
{
    <h3>Release mode</h3>
}

Upvotes: 21

For me, the code below has worked very well.

When the application is Debugging my buttons appear, when is Release, they don't.

@if (this.Context.IsDebuggingEnabled)
{
    <button type="button" class="btn btn-warning">Fill file</button>
    <button type="button" class="btn btn-info">Export file</button>
} 

Upvotes: 6

Shawn Wildermuth
Shawn Wildermuth

Reputation: 7458

I just created an extension method:

public static bool IsDebug(this HtmlHelper htmlHelper)
{
#if DEBUG
      return true;
#else
      return false;
#endif
}

Then used it in my views like so:

<section id="sidebar">
     @Html.Partial("_Connect")
     @if (!Html.IsDebug())
     { 
         @Html.Partial("_Ads")
     }
     <hr />
     @RenderSection("Sidebar", required: false)
</section>

Since the helper is compiled with the DEBUG/RELEASE symbol, it works.

Upvotes: 415

Sbu
Sbu

Reputation: 940

I know this is not a direct answer to the question but as I'm pretty sure debug configuration is corollary to the fact that you are actually executing locally, you can always use the Request.IsLocal property as a debug like test. Thus :

@if (Request.IsLocal)
{
    <link rel="stylesheet" type="text/css" href="~/css/compiled/complete.css">
}
else
{
    <link rel="stylesheet" type="text/css" href="~/css/compiled/complete.min.css">
}

Upvotes: 16

Yannick Richard
Yannick Richard

Reputation: 1249

By default MVC views are not compiled so #IF DEBUG can't work in a view. If you want to compile view in order to access IF DEBUG config, you need to :

  1. Right click on your project in Visual Studio
  2. Unload project
  3. Edit project

change the following attribute from false to true

<MvcBuildViews>true</MvcBuildViews>

reload your project and then views are going to be compiled.

The only other work around would be to have a function in your code behind

public static Boolean DEBUG(this System.Web.Mvc.WebViewPage page)
{
   var value = false;
   #if(DEBUG)
       value=true;
   #endif
   return value;
}

and then call it from view :

if(DEBUG())
{
  //debug code here
}
else
{
  //release code here
}

Upvotes: 5

Buildstarted
Buildstarted

Reputation: 26689

C# and ASP.NET MVC: Using #if directive in a view

Actually that answer has the right answer. You're going to have to pass whether or not you're in debug mode via the Model. (or ViewBag) since all views are compiled in debug mode.

Upvotes: 25

Related Questions