关于asp.net mvc:Razor视图引擎,如何进入预处理器(#if debug)

Razor view engine, how to enter preprocessor(#if debug)

我今天正在写我的第一页剃刀,不知道怎么进入#if debug #else #endif

如何在Razor中输入预处理器?


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

1
2
3
4
5
6
7
8
public static bool IsDebug(this HtmlHelper htmlHelper)
{
#if DEBUG
      return true;
#else
      return false;
#endif
}

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

1
2
3
4
5
6
7
8
9
<section id="sidebar">
     @Html.Partial("_Connect")
     @if (!Html.IsDebug())
     {
         @Html.Partial("_Ads")
     }
     <hr />
     @RenderSection("Sidebar", required: false)
</section>

因为助手是用调试/发布符号编译的,所以它可以工作。


它内置于HttpContext中:

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

在IMO中,这比对视图进行条件编译更有意义,并且对于某些测试场景非常方便。(见下文代码主管的评论。)

旁注:NullReferenceException用于HttpContext.Current

亚历克斯·安格斯提到,他们用这个解决方案得到了一个NullReferenceException,有一些人投了反对票,表明这可能不是一个孤立的事件。

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

如果您遇到此错误,请在注释中告诉我,并说明您是否正在使用预编译视图或任何可能导致您的视图在另一线程上部分呈现/执行的特殊设置!


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

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


我知道这不是问题的直接答案,但是我很确定调试配置是您实际在本地执行的事实的必然结果,因此您可以始终使用Request.IsLocal属性作为类似调试的测试。因此:

1
2
3
4
5
6
7
8
@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">
}


默认情况下,MVC视图不会编译,因此,如果调试无法在视图中工作,则不编译。如果要编译视图以访问if debug config,则需要:

  • 在Visual Studio中右键单击项目
  • 卸载工程
  • 编辑项目
  • 将以下属性从false更改为true

    1
    <MvcBuildViews>true</MvcBuildViews>

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

    唯一的其他解决方法是在代码后面有一个函数

    1
    2
    3
    4
    5
    6
    7
    8
    public static Boolean DEBUG(this System.Web.Mvc.WebViewPage page)
    {
       var value = false;
       #if(DEBUG)
           value=true;
       #endif
       return value;
    }

    然后从视图中调用它:

    1
    2
    3
    4
    5
    6
    7
    8
    if(DEBUG())
    {
      //debug code here
    }
    else
    {
      //release code here
    }

    我的解决方案很愚蠢,但它奏效了。在静态文件中的某个位置定义全局常量:

    1
    2
    3
    4
    5
    6
    7
    8
    public static class AppConstants
    {
    #if DEBUG
            public const bool IS_DEBUG = true;
    #else
            public const bool IS_DEBUG = false;
    #endif
    }

    然后在HTML中与Razor一起使用:

    1
    2
    3
    4
    5
    6
    7
    8
    @if (AppConstants.IS_DEBUG)
    {
        Debug mode
    }
    else
    {
        Release mode
    }


    对我来说,下面的代码运行得很好。

    当应用程序正在调试时,我的按钮会出现,当是释放时,它们不会出现。

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