剃刀视图引擎,如何进入预处理器(#if debug)


233

我今天在写我的第一个剃须刀页面,不知道如何输入 #if debug #else #endif

如何在剃须刀中输入预处理器?



10
我的观点是,您想要#if debug剃须刀,但这永远都是正确的。因此,您的问题的答案是这样做没有任何意义,因为Razor始终会在调试模式下进行编译。
2011年

4
@mamu您可以不接受该回答并接受Shawn的回答吗?
user247702 2014年

Answers:


370

我刚刚创建了一个扩展方法:

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

然后在我的视图中使用它,如下所示:

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

由于帮助程序是使用DEBUG / RELEASE符号进行编译的,因此它可以工作。


32
当然,这种扩展方法必须进入MVC项目,而不是进入可能用不同选项编译的单独库中……
Eric J.

2
这对我根本不起作用-无论编译模式如何,它都会产生“ True”。乔丹·格雷的答案非常完美。
蒂莫西·坎斯基

如果是DEBUG模式,则public static bool IsDebug(...){ return true; }对于非DEBUG模式,预处理器将基本上读取,反之亦然。
facepalm42

300

内置于HttpContext

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

IMO,这比对视图进行条件编译更有意义,并且在某些测试场景中非常有用。(请参阅下面的Tony Wall的评论。)


旁注:NullReferenceException用于HttpContext.Current

亚历克斯·安加斯(Alex Angas)提到他们可以NullReferenceException使用此解决方案,一些人对此表示反对,这可能不是一个孤立的事件。

我的最佳猜测:HttpContext.Current存储在中CallContext,这意味着它只能由处理传入HTTP请求的线程访问。如果您的视图是在不同的线程上呈现的(也许有一些预编译视图的解决方案?),您将获得的null价值HttpContext.Current

如果出现此错误,请在评论中让我知道,并提及您使用的是预编译视图还是任何可能导致您的视图在另一个线程上部分渲染/执行的特殊设置!


2
优点是您可以在集成测试环境中将其打开,以诊断只有在非开发人员PC上安装才能看到的部署问题。
Tony Wall,

2
我使用此方法得到一个空引用异常,这可能是因为在发布模式下,调试属性已从web.config中完全删除。
Alex Angas 2014年

1
@AlexAngas无法复制。:(我在.NET 4.5.1(ASP.NET MVC 5,System.Web版本4.0.0.0)中创建了一个项目,即使删除了该debug属性(或者实际上是整个compilation元素),我也没有遇到异常。最好的假设是这是在更高版本的System.Web程序集中已修复的错误,或者我不知道您的具体情况是否有所不同,您可以创建一个最小的测试项目并将其上传到某个地方吗?
Jordan Gray

4
@JordanGray感谢您的关注-我也刚刚尝试了一个新项目,也无法复制!您的解决方案正在工作。不幸的是,现在没有时间进一步看一下,但是如果我遇到原因,我将更新这篇文章。
亚历克斯·安加斯

5
血腥的聪明伴侣;这应该是OP的答案。
nocarrier

23

C#和ASP.NET MVC:在视图中使用#if指令

实际上,这个答案是正确的答案。您将必须通过模型来传递是否处于调试模式。(或ViewBag),因为所有视图都是在调试模式下编译的。


27
请注意,由于Razor视图始终以调试模式进行编译,因此以这种方式设置预处理程序指令实际上不会产生任何效果。您将永远执行// your debug stuff
marcind 2011年

1
嗯,是的,我刚写完就意识到了。
2011年

14

我知道这不是问题的直接答案,但是由于我敢肯定调试配置对您实际上是在本地执行这一事实是必然的,因此您始终可以将该Request.IsLocal属性用作调试(如test)。因此:

@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">
}

1
不必要。例如,您可能在测试/开发服务器上以“调试”模式运行,然后在“登台/生产”上以“发布”模式进行编译。
jonnybot '16

在这种情况下,呈现链接标记的html helper扩展方法会有所帮助。在扩展方法内部,您可以使用#if DEBUG或配置变量来确定环境。
sree

6

我的解决方案很愚蠢,但可以。在静态文件的某处定义全局常量:

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

然后将其与HTML中的Razor一起使用:

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

恕我直言,这不是那么愚蠢。在调试中,我想使用es6-javascript(因此在开发时会看到es6-错误),而在发行版中,我想使用自动转换的非es6-javascript(因为IE11不知道es6)。这对我来说是一个很好的解决方案。
Matthias Burger

谢谢马蒂亚斯!
tedebus

好人-简单直接,明确
Serexx

5

默认情况下,不会编译MVC视图,因此#IF DEBUG无法在视图中工作。如果要编译视图以访问IF DEBUG配置,则需要:

  1. 右键单击Visual Studio中的项目
  2. 卸载项目
  3. 编辑专案

将以下属性从false更改为true

<MvcBuildViews>true</MvcBuildViews>

重新加载您的项目,然后将要编译视图。

唯一的其他解决方法是在代码中包含一个函数

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

然后从视图调用它:

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

3

对我来说,下面的代码效果很好。

当应用程序为Debugging时,出现我的按钮,而Release为,则没有出现。

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

3

这在白标项目.net core 3.0中对我有用

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

2

在.NET Core中,您可以执行以下操作而不是检查预处理程序变量:

<environment include="Development">
  <!--Debug code here-->
</environment>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.