Razor View Engine, Eingabe des Präprozessors (#if Debug)


233

Ich schreibe heute meine erste Rasierseite und kann nicht herausfinden, wie ich eintreten soll #if debug #else #endif

Wie kann ich Präprozessor in Rasiermesser eingeben?



10
Mein Punkt ist, dass Sie #if debugin Rasiermesser wollen, aber es wird immer wahr sein. Die Antwort auf Ihre Frage lautet also, dass es keinen Sinn macht, dies zu tun, da Razor immer im Debug-Modus kompiliert wird.
Buildstarted

4
@mamu kannst du diese Antwort nicht akzeptieren und die von Shawn akzeptieren?
user247702

Antworten:


370

Ich habe gerade eine Erweiterungsmethode erstellt:

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

Dann benutzte es in meinen Ansichten so:

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

Da der Helfer mit dem DEBUG / RELEASE-Symbol kompiliert ist, funktioniert er.


32
Natürlich muss diese Erweiterungsmethode in das MVC-Projekt eingehen, nicht in eine separate Bibliothek, die möglicherweise mit verschiedenen Optionen kompiliert wird ...
Eric J.

2
Dies hat bei mir überhaupt nicht funktioniert - es hat "True" unabhängig vom Kompilierungsmodus erzeugt. Jordan Grays Antwort funktionierte perfekt.
Timothy Kanski

Wenn es sich um den DEBUG-Modus handelt, liest der Vorprozessor im Wesentlichen public static bool IsDebug(...){ return true; }und umgekehrt für den Nicht-DEBUG-Modus.
facepalm42

300

Dies ist eingebaut inHttpContext :

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

IMO, dies ist sinnvoller als die bedingte Kompilierung von Ansichten und für einige Testszenarien nützlich. (Siehe Tony Walls Kommentar unten.)


Randnotiz: NullReferenceExceptionfürHttpContext.Current

Alex Angas erwähnte, dass sie NullReferenceExceptionmit dieser Lösung eine Lösung finden, und einige Leute haben sich dafür ausgesprochen, dass dies möglicherweise kein Einzelfall ist.

Meine beste Vermutung: HttpContext.Currentwird in gespeichert CallContext, was bedeutet, dass nur der Thread darauf zugreifen kann, der die eingehende HTTP-Anforderung verarbeitet. Wenn Ihre Ansichten in einem anderen Thread gerendert werden (möglicherweise einige Lösungen für vorkompilierte Ansichten?), Erhalten Sie einen nullWert für HttpContext.Current.

Wenn Sie diesen Fehler erhalten, lassen Sie es mich bitte in den Kommentaren wissen und erwähnen Sie, ob Sie vorkompilierte Ansichten oder spezielle Einstellungen verwenden, die dazu führen könnten, dass Ihre Ansichten teilweise in einem anderen Thread gerendert / ausgeführt werden!


2
Hat den Vorteil, dass Sie es in Integrationstestumgebungen aktivieren können, um Bereitstellungsprobleme zu diagnostizieren, die häufig erst bei der Installation auf PCs ohne Entwickler auftreten.
Tony Wall

2
Ich erhalte damit eine Nullreferenzausnahme, wahrscheinlich weil im Release-Modus das Debug-Attribut vollständig aus web.config entfernt wird.
Alex Angas

1
@AlexAngas Kann nicht repro. :( Ich habe ein Projekt in .NET 4.5.1 (ASP.NET MVC 5, System.WebVersion 4.0.0.0) erstellt, und selbst wenn das debugAttribut (oder tatsächlich das gesamte compilationElement) entfernt wurde, erhalte ich keine Ausnahme. Mein nächstes Die besten Hypothesen sind, dass dies ein Fehler ist, der in späteren Versionen der System.WebAssembly behoben wurde, oder dass Ihre spezifische Situation etwas anderes ist, das mir nicht bekannt ist. Könnten Sie ein minimales Testprojekt erstellen und es irgendwo hochladen?
Jordan Gray

4
@JordanGray Vielen Dank für Ihren Blick - ich habe gerade ein neues Projekt ausprobiert und kann es auch nicht wiederholen! Ihre Lösung funktioniert. Im Moment leider keine Zeit, weiter zu schauen, aber wenn ich auf den Grund stoße, werde ich diesen Beitrag aktualisieren.
Alex Angas

5
Verdammt brillanter Kumpel; Dies sollte die Antwort des OP sein.
Nocarrier

23

C # und ASP.NET MVC: Verwenden der Direktive #if in einer Ansicht

Eigentlich hat diese Antwort die richtige Antwort. Sie müssen über das Modell übergeben, ob Sie sich im Debug-Modus befinden oder nicht. (oder ViewBag), da alle Ansichten im Debug-Modus kompiliert werden.


27
Beachten Sie, dass das Festlegen einer Präprozessor-Direktive auf diese Weise keine Auswirkungen hat, da Razor-Ansichten immer im Debug-Modus kompiliert werden. Sie werden immer ausführen// your debug stuff
Marcind

1
Heh, ja, das habe ich gerade gemerkt, als ich es geschrieben habe.
Buildstarted

14

Ich weiß, dass dies keine direkte Antwort auf die Frage ist, aber da ich ziemlich sicher bin, dass die Debug-Konfiguration mit der Tatsache zusammenhängt, dass Sie tatsächlich lokal ausgeführt werden, können Sie die Request.IsLocalEigenschaft immer als Debug-ähnlichen Test verwenden. Also:

@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
Nicht unbedingt. Sie können beispielsweise im Debug-Modus auf einem Test- / Entwicklungsserver ausgeführt werden, bevor Sie im Release-Modus in Staging / Production kompilieren.
Jonnybot

In diesem Fall hilft eine HTML-Hilfserweiterungsmethode zum Rendern des Link-Tags. Innerhalb der Erweiterungsmethode können Sie entweder #if DEBUG oder eine Konfigurationsvariable verwenden, um die Umgebung zu bestimmen.
Sree

6

Meine Lösung ist sehr dumm, aber es funktioniert. Definieren Sie eine globale Konstante irgendwo in einer statischen Datei:

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

Verwenden Sie es dann mit Razor in HTML:

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

Imho, es ist nicht so dumm. Beim Debuggen möchte ich das es6-Javascript verwenden (damit ich die es6-Fehler während der Entwicklung sehe) und im Release möchte ich das automatisch konvertierte Nicht-es6-Javascript verwenden (weil IE11 es6 nicht kennt). Das ist eine großartige Lösung für mich.
Matthias Burger

Danke Matthias!
Tedebus

schön - einfach direkt, eindeutig
Serexx

5

Standardmäßig werden MVC-Ansichten nicht kompiliert, sodass #IF DEBUG in einer Ansicht nicht funktionieren kann. Wenn Sie die Ansicht kompilieren möchten, um auf die IF DEBUG-Konfiguration zuzugreifen, müssen Sie:

  1. Klicken Sie in Visual Studio mit der rechten Maustaste auf Ihr Projekt
  2. Projekt entladen
  3. Projekt bearbeiten

Ändern Sie das folgende Attribut von false in true

<MvcBuildViews>true</MvcBuildViews>

Laden Sie Ihr Projekt neu und dann werden Ansichten kompiliert.

Die einzige andere Möglichkeit wäre, eine Funktion in Ihrem Code zu haben

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

und dann aus der Sicht aufrufen:

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

3

Für mich hat der folgende Code sehr gut funktioniert.

Wenn die Anwendung debuggt, werden meine Schaltflächen angezeigt, wenn Release ist , werden sie nicht angezeigt .

@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

Dies funktioniert bei mir in einem White-Label-Projekt .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

In .NET Core können Sie Folgendes tun, anstatt die Präprozessorvariablen zu überprüfen:

<environment include="Development">
  <!--Debug code here-->
</environment>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.