C# and ASP.NET MVC: Using #if directive in a view
In your model:
bool isRelease = false;
<% #if (RELEASE) %>
isRelease = true;
<% #endif %>
In your view:
<% if (Model.isRelease) { %>
<div class="releaseBanner">Banner text here</div>
<% } else { %>
<div class="debugBanner">Banner text here</div>
<% } %>
Pre-processing equivalent for views in RAZOR/MVC 3
That's too messy IMO. Views should be dumb, and focused on rendering HTML, not making build-based decisions.
Set properties in your view model if debug is configured, and render them out in the View.
If the properties are null (e.g non-debug), nothing will get rendered.
Preprocessor directives per launch settings in .Net Core
The problem with your question is that a preprocessor directive is used and evaluated at compile time, not run time. So if you want a "easy" switch, you have to define it in your csproj
as a build configuration. You have to add a build configuration to your csproj
file:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WebListener|AnyCPU'">
<DefineConstants>DEBUG</DefineConstants>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='IISExpress|AnyCPU'">
<DefineConstants>DEBUG</DefineConstants>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
</PropertyGroup>
And you have to add the information, which build configurations are awailable:
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<Configurations>Debug;Release;WebListener;IISExpress</Configurations>
</PropertyGroup>
so you can use your code as example
#if WEBLISTENER
.UseWebListener(options =>
{
options.ListenerSettings.Authentication.Schemes = AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM;
options.ListenerSettings.Authentication.AllowAnonymous = false;
})
#endif
#if IISEXPRESS
/* ... */
#endif
BUT: With this solution you have to change both, the launch settings AND the build settings, to switch between your configurations:
For more information you can look into these ressources:
- Creating custom build configurations for the .NET Core project format
- How to use custom preprocessor directives in .Net Core
How to use Preprocessor directives in MVC aspx pages
You can use the following:
if (!HttpContext.Current.IsDebuggingEnabled)
Script = OptimizeScript(Script);
Further.....there are a couple of comments than discuss the topic further.
From Wilco Bauwer he comments that this property encapsulates the web.config setting and doesn't take the page level debugging into account and if you wanted to....
bool isDebuggingEnabled = Assembly.GetExecutingAssembly().IsDefined(typeof(DebuggableAttribute));
....this is the kiddy to achieve it!!
and Peter Bromberg (C# MVP) offers up another solution using the Global.asax.cs file and a static global application flag being set in the Application_Start event.
public static bool IsDebugMode = false;
protected void Application_Start(object sender, EventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached) IsDebugMode = true;
Taken from Steves blog
What does @using and @namespace directives do in a Razor _ViewImports.cshtml file?
Whatever namespaces you mention using @namespace
in the ViewImports.cshtml file will be available to your views (.cshtml files) automatically without the use of @using
. In other words, they will be available implicitly. If not mentioned in the ViewImports.cshtml file, you will still need to use @using
.
From documentation
The @namespace directive was designed so the C# classes added to a project and pages-generated code just work without having to add an @using directive for the code behind file.
In other words, if you add the @namespace
to the _ViewImports.cshtml file, then the other files will not need to use @using
in each one of them.
What is _ViewImports.cshtml`?
From the docs:
_ViewImports.cshtml serves one major purpose: to provide namespaces which can be used by all other views. In previous MVC projects, this functionality was provided by the web.config file in the Views folder; since the web.config no longer exists, global namespaces are now provided by this file.
More Explanation
In MVC5 and earlier versions, if you check the Views/web.config file, you will notice xml and amongst it you will notice this or possible more <add
elements:
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Mvc" />
</namespaces>
That is basically instructing the Razor engine, that all the .cshtml files within this specific Views folder will need those namespaces and thus the .cshtml files can use those namespaces without @using
for these namespaces. In MVC6, the Views/web.config no longer exists and it is replaced by ViewImports.cshtml file which serves the same purpose.
Ok great, so what is @using for then?
You will still need @using
in the .cshtml files for whatever namespaces are not imported using @namespace
in the ViewImports.cshtml file. For example, if you have a view named Edit.cshtml, then you may have this:
@using NamespaceA;
Which means this namespace is imported explicitly to be available for Edit.cshmtl file. A few other namespaces, which are mentioned in ViewImport.cshtml file will be automatically available to Edit.cshtml file.
is there a tool to propagate preprocessor directives?
No, basically. However, what you can do is split your code into two files and make use of partial class
such that all your bar
code is in one isolated file:
partial class foo
{
partial void OnBar(bool value);
public void Do()
{
OnBar(false);
}
}
and
#if bar
partial class foo
{
private bool bar;
partial void OnBar(bool value)
{
bar = value;
}
}
#endif
Now the main file knows nothing about bar
. If the bar
compilation symbol isn't defined, the bar
field doesn't exist, and nor does the OnBar
method - the method and it's invocations simply evaporate.
This can be useful in many scenarios, including additional levels of debugging code, or targeting multiple platforms / frameworks / operating systems (with specific files for different targets) - without your code being filled with #if
.
How to follow preprocessor directives throughout a compilation
I think you're on the right track with the /P
option, but the doc states that the output will go to files with a .i
extension (so probably not to your Output window).
Further, you may be able to find some help on any linker errors by generating a map file; see /MAP (Generate Mapfile).
Related Topics
Options for Embedding Chromium Instead of Ie Webbrowser Control with Wpf/C#
How to Quickly Check If Two Data Transfer Objects Have Equal Properties in C#
Kill Process Tree Programmatically in C#
JSON Deserialization to C# with Dynamic Keys
How to Get Intptr from Byte[] in C#
Read Post Data Submitted to ASP.NET Form
How to Pass SQLparameter to In()
How to Connect to an Mdf Database File
How to Drag and Move Shapes in C#
What Is Managed or Unmanaged Code in Programming
Entity Framework - Code First - Can't Store List<String>
Best Way in .Net to Manage Queue of Tasks on a Separate (Single) Thread
Transparent Images with C# Winforms
Calling Function from Generated Button in Blazor
The Need for Volatile Modifier in Double Checked Locking in .Net