Silnik widoku Razor, jak wejść w preprocesor (debugowanie #if)

233

Piszę dziś moją pierwszą stronę z ostrzami, nie mogę wymyślić, jak wejść #if debug #else #endif

Jak mogę wprowadzić preprocesor w maszynce do golenia?

mamu
źródło
możliwy duplikat stackoverflow.com/questions/378982/…
Handcraftsman
10
Chodzi mi o to, że chcesz mieć #if debugbrzytwę, ale zawsze będzie to prawdą. Odpowiedź na twoje pytanie jest taka, że ​​nie ma sensu tego robić, ponieważ Razor zawsze kompiluje się w trybie debugowania.
Buildstarted
4
@mamu, czy możesz odrzucić tę odpowiedź i zaakceptować tę z Shawna?
user247702

Odpowiedzi:

370

Właśnie utworzyłem metodę rozszerzenia:

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

Następnie użyłem go w moich widokach tak:

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

Ponieważ pomocnik jest skompilowany z symbolem DEBUG / RELEASE, działa.

Shawn Wildermuth
źródło
32
Oczywiście ta metoda rozszerzenia musi przejść do projektu MVC, a nie do osobnej biblioteki, którą można skompilować z różnymi opcjami ...
Eric J.,
2
Nie działało to dla mnie wcale - dawało „True” niezależnie od trybu kompilacji. Odpowiedź Jordana Graya działała idealnie.
Timothy Kanski
Jeśli jest to tryb DEBUG, procesor wstępny będzie w zasadzie czytał public static bool IsDebug(...){ return true; }i na odwrót w trybie innym niż DEBUG.
facepalm42
300

Jest to wbudowane wHttpContext :

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

IMO ma to bardziej sens niż kompilacja warunkowa dla widoków i jest przydatna w niektórych scenariuszach testowych. (Zobacz komentarz Tony'ego Walla poniżej.)


Uwaga dodatkowa: NullReferenceExceptiondlaHttpContext.Current

Alex Angas wspomniał , że dostają NullReferenceExceptionto rozwiązanie, a kilka osób wyraziło opinię, że nie może to być pojedyncze wydarzenie.

Moje najlepsze przypuszczenie: HttpContext.Currentjest przechowywane CallContext, co oznacza, że ​​jest dostępne tylko dla wątku, który obsługuje przychodzące żądanie HTTP. Jeśli twoje widoki są renderowane w innym wątku (być może niektóre rozwiązania dla widoków wstępnie skompilowanych?), Otrzymasz nullwartość HttpContext.Current.

Jeśli pojawi się ten błąd, daj mi znać w komentarzach i podaj, czy używasz wstępnie skompilowanych widoków lub jakiejkolwiek specjalnej konfiguracji, która może spowodować częściowe renderowanie / wykonanie twoich widoków w innym wątku!

Jordan Gray
źródło
2
Ma tę zaletę, że można ją włączyć w testowych środowiskach integracji, aby zdiagnozować problemy z wdrażaniem, które często nie są widoczne, dopóki nie zostaną zainstalowane na komputerach innych niż deweloper.
Tony Wall
2
Otrzymuję wyjątek odniesienia zerowego przy użyciu tego, prawdopodobnie dlatego, że w trybie Release atrybut debugowania jest całkowicie usuwany z pliku web.config.
Alex Angas
1
@AlexAngas Can't repro. :( Stworzyłem projekt w .NET 4.5.1 (ASP.NET MVC 5, System.Webwersja 4.0.0.0) i nawet z usuniętym debugatrybutem (a nawet całym compilationelementem) nie otrzymuję wyjątku. Mój następny najlepsze hipotezy są takie, że jest to błąd, który został naprawiony w późniejszych wersjach System.Webzestawu lub że jest coś innego w twojej konkretnej sytuacji, o czym nie jestem świadomy. Czy możesz stworzyć minimalny projekt testowy i przesłać go gdzieś?
Jordan Gray
4
@JordanGray Dziękuję za spojrzenie - właśnie wypróbowałem nowy projekt i nie mogę go też repro! Twoje rozwiązanie działa. Niestety nie ma czasu na dalsze poszukiwania, ale jeśli napotkam powód, zaktualizuję ten post.
Alex Angas,
5
Cholernie genialny partner; taka powinna być odpowiedź PO.
nocarrier
23

C # i ASP.NET MVC: Używanie dyrektywy #if w widoku

Właściwie ta odpowiedź ma właściwą odpowiedź. Będziesz musiał przejść niezależnie od tego, czy jesteś w trybie debugowania za pośrednictwem modelu. (lub ViewBag), ponieważ wszystkie widoki są kompilowane w trybie debugowania.

Buildstarted
źródło
27
Zauważ, że ponieważ widoki Razor są zawsze kompilowane w trybie debugowania, ustawienie dyrektywy preprocesora w ten sposób nie będzie miało żadnego efektu. Zawsze będziesz wykonywać egzekucje// your debug stuff
marcind
1
Hej, tak, właśnie zdałem sobie z tego sprawę, kiedy to napisałem.
Buildstarted
14

Wiem, że nie jest to bezpośrednia odpowiedź na pytanie, ale ponieważ jestem pewien, że konfiguracja debugowania jest następstwem faktu, że faktycznie wykonuje się lokalnie, zawsze można użyć Request.IsLocalwłaściwości jako testu debugowania. Zatem:

@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
źródło
1
Niekoniecznie. Możesz na przykład uruchomić w trybie debugowania na serwerze testowym / programistycznym przed kompilacją w trybie zwolnienia na etapie testowania / produkcji.
jonnybot
W tym przypadku pomoże metoda rozszerzenia pomocnika HTML do renderowania znacznika link. W metodzie rozszerzenia możesz użyć #if DEBUG lub zmiennej config, aby zdecydować o środowisku.
sree
6

Moje rozwiązanie jest bardzo głupie, ale działa. Zdefiniuj gdzieś stałą globalną w pliku statycznym:

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

Następnie użyj go z Razor w HTML:

@if (AppConstants.IS_DEBUG)
{
    <h3>Debug mode</h3>
}
else
{
    <h3>Release mode</h3>
}
Tedebus
źródło
imho, to nie jest takie głupie. w debugowaniu chcę używać języka es6-javascript (więc podczas programowania widzę błędy es6), aw wydaniu chcę używać automatycznie przekonwertowanego kodu JavaScript innego niż es6 (ponieważ IE11 nie zna es6). to dla mnie świetne rozwiązanie.
Matthias Burger,
Dziękuję Matthias!
tedebus
ładny - prosty bezpośredni, jednoznaczny
Serexx
5

Domyślnie widoki MVC nie są kompilowane, więc #IF DEBUG nie może działać w widoku. Jeśli chcesz skompilować widok w celu uzyskania dostępu do konfiguracji IF DEBUG, musisz:

  1. Kliknij prawym przyciskiem myszy swój projekt w Visual Studio
  2. Zwolnij projekt
  3. Edytuj projekt

zmień następujący atrybut z false na true

<MvcBuildViews>true</MvcBuildViews>

ponownie załaduj projekt, a następnie zostaną skompilowane widoki.

Jedynym innym rozwiązaniem byłoby posiadanie funkcji w kodzie

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

a następnie nazwij to z widoku:

if(DEBUG())
{
  //debug code here
}
else
{
  //release code here
}
Yannick Richard
źródło
3

Dla mnie poniższy kod działał bardzo dobrze.

Gdy aplikacja jest debugowana, pojawiają się moje przyciski, kiedy jest wersja , nie są.

@if (this.Context.IsDebuggingEnabled)
{
    <button type="button" class="btn btn-warning">Fill file</button>
    <button type="button" class="btn btn-info">Export file</button>
} 
Matheus Fernandes Amorim
źródło
3

Działa to dla mnie w projekcie białej etykiety .net core 3.0

    @{
    #if CORPA
    }
         <button type="button" class="btn btn-warning">A Button</button>
    @{
    #else
    }
         <p>Nothing to see here</p>
    @{
    #endif
    }
Perry Armstrong
źródło
2

W .NET Core można wykonać następujące czynności zamiast sprawdzania zmiennych preprocesora:

<environment include="Development">
  <!--Debug code here-->
</environment>
beleester
źródło