Движок Razor View, как войти в препроцессор (#if debug)

234

Я пишу свою первую страницу бритвы сегодня, не могу понять, как войти #if debug #else #endif

Как я могу ввести препроцессор в бритву?

Маму
источник
возможный дубликат stackoverflow.com/questions/378982/…
Handcraftsman
10
Я хочу #if debugсказать, что ты хочешь бритву, но это всегда будет правдой. Таким образом, ответ на ваш вопрос заключается в том, что делать это бессмысленно, поскольку Razor всегда будет компилироваться в режиме отладки.
Buildstarted
4
@mamu можешь ли ты отказаться от ответа и принять ответ от Шона?
user247702

Ответы:

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, а не в отдельную библиотеку, которая может быть скомпилирована с различными параметрами ...
Эрик Дж
2
У меня это вообще не сработало - оно выдает «True» независимо от режима компиляции. Ответ Джордана Грея сработал отлично.
Тимоти Кански
Если это режим отладки, препроцессор будет по существу читать public static bool IsDebug(...){ return true; }, и наоборот для режима без отладки.
facepalm42
300

Это встроено вHttpContext :

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

ИМО, это имеет больше смысла, чем условная компиляция для представлений и пригодится для некоторых сценариев тестирования. (См . Комментарий Тони Уолла ниже.)


Примечание стороны: NullReferenceExceptionдляHttpContext.Current

Алекс Ангас упомянул, что они получили NullReferenceExceptionэто решение, и несколько человек проголосовали, указав, что это не может быть единичным событием.

Мое лучшее предположение: HttpContext.Currentхранится в том CallContextсмысле, что он доступен только потоку, который обрабатывает входящий HTTP-запрос. Если ваши представления отображаются в другом потоке (возможно, некоторые решения для предварительно скомпилированных представлений?), Вы получите nullзначение для HttpContext.Current.

Если вы получили эту ошибку, пожалуйста, дайте мне знать в комментариях и укажите, используете ли вы предварительно скомпилированные представления или что-то особенное, что может привести к частичной визуализации / выполнению ваших представлений в другом потоке!

Джордан Грей
источник
2
Имеет то преимущество, что вы можете включить его в интеграционных тестовых средах для диагностики проблем развертывания, которые часто не видны до тех пор, пока не будут установлены на ПК, не предназначенные для разработчиков.
Тони Уолл
2
Я получаю исключение нулевой ссылки, используя это, вероятно, потому что в режиме Release атрибут debug полностью удаляется из web.config.
Алекс Ангас
1
@AlexAngas Невозможно воспроизвести. :( Я создал проект в .NET 4.5.1 (ASP.NET MVC 5, System.Webверсия 4.0.0.0), и даже с удаленным debugатрибутом (или, действительно, целым compilationэлементом) я не получаю исключения. Мой следующий лучшая гипотеза состоит в том, что это ошибка, которая была исправлена ​​в более поздних версиях System.Webсборки, или что в вашей конкретной ситуации есть что-то другое, о чем я не знаю. Не могли бы вы создать минимальный тестовый проект и загрузить его куда-нибудь?
Джордан Грей
4
@JordanGray Спасибо, что заглянули - я только что попробовал новый проект и не могу его воспроизвести! Ваше решение работает. К сожалению, сейчас нет времени смотреть дальше, но если я найду причину, я обновлю этот пост.
Алекс Ангас
5
Кровавый блестящий приятель; это должен быть ответ ОП.
нокарьер
23

C # и ASP.NET MVC: использование директивы #if в представлении

На самом деле этот ответ имеет правильный ответ. Вам нужно будет передать, находитесь ли вы в режиме отладки через модель. (или ViewBag), поскольку все представления компилируются в режиме отладки.

Buildstarted
источник
27
Обратите внимание, что, поскольку представления Razor всегда компилируются в режиме отладки, установка директивы препроцессора таким образом фактически не будет иметь никакого эффекта. Вы всегда будете казнить// your debug stuff
Марсинд
1
Хех, да, я только что понял это, когда написал это.
Buildstarted
14

Я знаю, что это не прямой ответ на вопрос, но, поскольку я почти уверен, что конфигурация отладки является следствием того факта, что вы на самом деле выполняете локально, вы всегда можете использовать это Request.IsLocalсвойство как отладочный тест. Таким образом:

@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">
}
Sbu
источник
1
Не обязательно. Вы можете запустить в режиме отладки на тестовом сервере / сервере разработки, например, перед компиляцией в режиме выпуска в Staging / Production.
Джоннибот
В этом случае поможет метод расширения html-помощника для отображения тега ссылки. Внутри метода расширения вы можете использовать #if DEBUG или переменную config для определения среды.
Сри
6

Мое решение очень глупо, но оно работает. Определите глобальную константу где-нибудь в статическом файле:

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

Затем используйте его с Razor в HTML:

@if (AppConstants.IS_DEBUG)
{
    <h3>Debug mode</h3>
}
else
{
    <h3>Release mode</h3>
}
tedebus
источник
Имхо, это не так глупо. в отладке я хочу использовать es6-javascript (поэтому я вижу ошибки es6 при разработке), а в релизе я хочу использовать автоматически преобразованный не es6-javascript (потому что IE11 не знает es6). это отличное решение для меня.
Матиас Бургер
Спасибо Матиас!
Тедебус
хороший - простой прямой, однозначный
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

Для меня код ниже работал очень хорошо.

Когда приложение отлаживается, у меня появляются кнопки, а при отпускании - нет.

@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

Это работает для меня в проекте white label .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>
beleester
источник