Moteur de visualisation Razor, comment entrer dans le préprocesseur (#if debug)

234

J'écris ma première page de rasoir aujourd'hui, je ne sais pas comment entrer #if debug #else #endif

Comment puis-je entrer le préprocesseur dans le rasoir?

Mamu
la source
doublon possible de stackoverflow.com/questions/378982/…
Artisan
10
Mon point est que vous voulez un #if debugrasoir, mais ce sera toujours vrai. Donc, la réponse à votre question est qu'il n'y a aucun intérêt à le faire car Razor compilera toujours en mode débogage.
Buildstarted
4
@mamu pouvez-vous refuser cette réponse et accepter celle de Shawn?
user247702

Réponses:

370

Je viens de créer une méthode d'extension:

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

Ensuite, je l'ai utilisé dans mes vues comme ceci:

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

Puisque l'assistant est compilé avec le symbole DEBUG / RELEASE, cela fonctionne.

Shawn Wildermuth
la source
32
Bien sûr, cette méthode d'extension doit aller dans le projet MVC, pas dans une bibliothèque séparée qui pourrait être compilée avec différentes options ...
Eric J.
2
Cela ne fonctionnait pas du tout pour moi - cela produisait "True" quel que soit le mode de compilation. La réponse de Jordan Gray a parfaitement fonctionné.
Timothy Kanski
S'il s'agit du mode DEBUG, le pré-processeur lira essentiellement public static bool IsDebug(...){ return true; }, et vice versa pour le mode non DEBUG.
facepalm42
300

Ceci est construit pourHttpContext :

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

OMI, cela a plus de sens que la compilation conditionnelle pour les vues et est pratique pour certains scénarios de test. (Voir le commentaire de Tony Wall ci-dessous.)


Note latérale: NullReferenceExceptionpourHttpContext.Current

Alex Angas a mentionné qu'ils obtiennent un NullReferenceExceptionavec cette solution, et quelques personnes ont voté pour indiquer que ce n'est peut-être pas un événement isolé.

Ma meilleure estimation: HttpContext.Currentest stocké dans CallContext, ce qui signifie qu'il n'est accessible que par le thread qui gère la demande HTTP entrante. Si vos vues sont rendues sur un thread différent (peut-être des solutions pour les vues précompilées?), Vous obtiendrez une nullvaleur pour HttpContext.Current.

Si vous obtenez cette erreur, faites-le moi savoir dans les commentaires et mentionnez si vous utilisez des vues précompilées ou quelque chose de spécial qui pourrait entraîner le rendu / exécution partiel de vos vues sur un autre thread!

Jordan Grey
la source
2
A l'avantage que vous pouvez l'activer dans les environnements de test d'intégration pour diagnostiquer les problèmes de déploiement qui ne sont souvent pas vus jusqu'à ce qu'ils soient installés sur des PC non développeurs.
Tony Wall
2
J'obtiens une exception de référence nulle en utilisant ceci, probablement parce qu'en mode Release, l'attribut de débogage est entièrement supprimé de web.config.
Alex Angas
1
@AlexAngas Impossible de reproduire. :( J'ai créé un projet dans .NET 4.5.1 (ASP.NET MVC 5, System.Webversion 4.0.0.0), et même avec l' debugattribut (ou, en fait, l' compilationélément entier ) supprimé, je ne reçois pas d'exception. Mon prochain les meilleures hypothèses sont qu'il s'agit d'un bogue qui a été corrigé dans les versions ultérieures de l' System.Webassembly ou qu'il y a quelque chose de différent dans votre situation spécifique que je ne connais pas. Pourriez-vous créer un projet de test minimal et le télécharger quelque part?
Jordan Gray
4
@JordanGray Merci d'avoir jeté un coup d'œil - je viens également d'essayer un nouveau projet et je ne peux pas non plus le reprocher! Votre solution fonctionne. Pas le temps de regarder plus loin pour le moment malheureusement, mais si je tombe sur la raison pour laquelle je mettrai à jour ce post.
Alex Angas
5
Compagnon brillant sanglant; ce devrait être la réponse des PO.
nocarrier
23

C # et ASP.NET MVC: utilisation de la directive #if dans une vue

En fait, cette réponse a la bonne réponse. Vous devrez passer si vous êtes ou non en mode débogage via le modèle. (ou ViewBag) car toutes les vues sont compilées en mode débogage.

Buildstarted
la source
27
Notez que parce que les vues Razor sont toujours compilées en mode débogage, la définition d'une directive de préprocesseur de cette manière n'aura aucun effet. Vous exécuterez toujours// your debug stuff
marcind
1
Hé, ouais, je viens de réaliser ça quand je l'ai écrit.
Début du
14

Je sais que ce n'est pas une réponse directe à la question, mais comme je suis presque sûr que la configuration de débogage est corollaire du fait que vous exécutez réellement localement, vous pouvez toujours utiliser la Request.IsLocalpropriété comme test de débogage. Donc :

@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
la source
1
Pas nécessairement. Vous pouvez exécuter en mode Débogage sur un serveur de test / développement, par exemple, avant de compiler en mode Release sur Staging / Production.
jonnybot
Une méthode d'extension d'assistance html pour rendre la balise de lien aidera dans ce cas. Dans la méthode d'extension, vous pouvez utiliser #if DEBUG ou une variable de configuration pour décider de l'environnement.
Sree
6

Ma solution est très stupide, mais ça marche. Définissez une constante globale quelque part dans un fichier statique:

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

Ensuite, utilisez-le avec Razor en HTML:

@if (AppConstants.IS_DEBUG)
{
    <h3>Debug mode</h3>
}
else
{
    <h3>Release mode</h3>
}
tedebus
la source
à mon humble avis, ce n'est pas si stupide. dans le débogage, je veux utiliser le es6-javascript (donc je vois les erreurs es6 lors du développement) et dans la version, je veux utiliser le non-es6-javascript converti automatiquement (cuz IE11 ne connaît pas es6). c'est une excellente solution pour moi.
Matthias Burger
Merci Matthias!
tedebus
nice one - simple direct, unambiguous
Serexx
5

Par défaut, les vues MVC ne sont pas compilées, donc #IF DEBUG ne peut pas fonctionner dans une vue. Si vous souhaitez compiler la vue pour accéder à la configuration IF DEBUG, vous devez:

  1. Faites un clic droit sur votre projet dans Visual Studio
  2. Décharger le projet
  3. Modifier le projet

changer l'attribut suivant de faux à vrai

<MvcBuildViews>true</MvcBuildViews>

rechargez votre projet et les vues vont être compilées.

La seule autre solution consiste à avoir une fonction dans votre code derrière

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

puis appelez-le de vue:

if(DEBUG())
{
  //debug code here
}
else
{
  //release code here
}
Yannick Richard
la source
3

Pour moi, le code ci-dessous a très bien fonctionné.

Lorsque l'application est en train de déboguer, mes boutons apparaissent, quand est Release , ils ne le font pas.

@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
la source
3

Cela fonctionne pour moi dans un projet en marque blanche .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
la source
2

Dans .NET Core, vous pouvez effectuer les opérations suivantes au lieu de vérifier les variables du préprocesseur:

<environment include="Development">
  <!--Debug code here-->
</environment>
Belester
la source