Comment utiliser ? : instructions if avec Razor et blocs de code en ligne

154

Je mets à jour mes anciennes vues .aspx avec le nouveau moteur de vue Razore. J'ai un tas d'endroits où j'ai du code comme celui-ci:

<span class="vote-up<%= puzzle.UserVote == VoteType.Up ? "-selected" : "" %>">Vote Up</span>

Idéalement, j'aimerais faire ceci:

<span class="vote-up@{puzzle.UserVote == VoteType.Up ? "-selected" : ""}">Vote Up</span>

Cependant, il y a deux problèmes ici:

  1. vote-up@{puzzle.UserVote .... ne traite pas le symbole @ comme le début d'un bloc de code
  2. @puzzle.UserVote == VoteType.Upregarde la première partie @puzzle.UserVotecomme si elle était censée rendre la valeur de la variable.

Quelqu'un sait comment résoudre ces problèmes?

Michée
la source
6
Je n'ai pas utilisé Razor mais en fonction de ce que je vois, essayez@(puzzle.UserVote == VoteType.Up ? "-selected" : "")
Lasse Espeholt
Comme il s'agit du meilleur résultat pour les opérateurs ternaires en ligne dans razor, j'ajouterai que si votre sortie contient des caractères html ou encodables tels que des apostrophes, par @(isSomething ? "class='test'" : "")exemple en injectant du javascript ou similaire, il les encodera comme des entités comme &#39;et cassera la page. Vous devez donc utiliser Html.Raw(".."). Sinon, avec le code ci-dessus, vous vous retrouveriez avec quelque chose comme <p class=&#39;test&#39;>qui n'est pas valide.
NibblyPig

Réponses:

299

Cela devrait fonctionner:

<span class="vote-up@(puzzle.UserVote == VoteType.Up ? "-selected" : "")">Vote Up</span>
CD..
la source
2
très étrange d'utiliser le paren plutôt que l'accolade
pat capozzi
32

La clé est d'encapsuler l'expression entre parenthèses après le délimiteur @. Vous pouvez faire fonctionner n'importe quelle expression composée de cette façon.

JPC
la source
28
@( condition ? "true" : "false" )
Daniel Santos
la source
1
Je suis allé pour celui-ci, je me sens propre et est facile à relire plus tard
Dan Harris
1
Si vous avez besoin d'afficher la valeur d'une propriété (y compris une chaîne) plutôt que d'appeler ToString () - Ce qui n'a pas fonctionné dans mon cas. Vous pouvez faire ceci @ (condition? $ "{Foo.bar}": "Default")
Dan Harris
6

Dans la plupart des cas, la solution de CD .. fonctionnera parfaitement bien. Cependant, j'avais une situation un peu plus tordue:

 @(String.IsNullOrEmpty(Model.MaidenName) ? "&nbsp;" : Model.MaidenName)

Cela m'imprimerait "& nbsp;" dans ma page, respectivement générer la source &amp;nbsp;. Maintenant, il existe une fonction Html.Raw("&nbsp;")qui est censée vous permettre d'écrire du code source, sauf que dans cette constellation, elle génère une erreur de compilation:

Message d'erreur du compilateur: CS0173: Le type d'expression conditionnelle ne peut pas être déterminé car il n'y a pas de conversion implicite entre 'System.Web.IHtmlString' et 'string'

J'ai donc fini par écrire une déclaration comme celle-ci, qui est moins agréable mais fonctionne même dans mon cas:

@if (String.IsNullOrEmpty(Model.MaidenName)) { @Html.Raw("&nbsp;") } else { @Model.MaidenName } 

Remarque: ce qui est intéressant, c'est qu'une fois que vous êtes à l'intérieur de l'accolade, vous devez redémarrer un bloc Razor.

Damian Vogel
la source
Pourquoi pas juste@(String.IsNullOrEmpty(Model.MaidenName) ? Html.Raw("&nbsp;") : Model.MaidenName)
JP Hellemons
Uhm .. que diriez-vous à cause de l'erreur de compilation susmentionnée? ;)
Damian Vogel
3
Désolé, j'ai besoin de plus de café :)
JP Hellemons
1
Vous pouvez éviter cette erreur en faisant des deux côtés de l'opérateur ternaire le même type,@(String.IsNullOrEmpty(Model.MaidenName) ? Html.Raw("&nbsp;") : Html.Raw(Model.MaidenName))
NibblyPig