Como usar ? : se declarações com Razor e blocos de código embutido

154

Estou atualizando minhas exibições .aspx antigas com o novo mecanismo de exibição Razore. Eu tenho vários lugares onde eu tenho código assim:

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

Idealmente, eu gostaria de fazer isso:

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

No entanto, existem dois problemas aqui:

  1. vote-up@{puzzle.UserVote .... não está tratando o símbolo @ como o início de um bloco de código
  2. @puzzle.UserVote == VoteType.Upolha para a primeira parte @puzzle.UserVotecomo se fosse para renderizar o valor da variável.

Alguém sabe como resolver esses problemas?

Micah
fonte
6
Eu não usei o Razor, mas com base no que estou vendo, tente@(puzzle.UserVote == VoteType.Up ? "-selected" : "")
Lasse Espeholt
Como este é o principal resultado para operadores ternários em linha no razor, acrescentarei que, se sua saída contiver caracteres html ou codificáveis, como apóstrofes, por @(isSomething ? "class='test'" : "")exemplo , por exemplo, injetar javascript ou similar, ele os codificará como entidades &#39;e quebrará a página. Então você deve usar Html.Raw(".."). Caso contrário, com o código acima, você terminará com algo como o <p class=&#39;test&#39;>que é inválido.
NibblyPig

Respostas:

298

Isso deve funcionar:

<span class="vote-up@(puzzle.UserVote == VoteType.Up ? "-selected" : "")">Vote Up</span>
CD..
fonte
2
muito estranho usar o parêntese em vez da chave
Capozzi pat
32

A chave é encapsular a expressão entre parênteses após o delimitador @. Você pode fazer qualquer expressão composta funcionar dessa maneira.

JPC
fonte
28
@( condition ? "true" : "false" )
Daniel Santos
fonte
1
Eu fui para um presente, sente-se limpa e é fácil de ler mais tarde
Dan Harris
1
Se você precisar exibir o valor de uma propriedade (incluindo uma string) em vez de chamar ToString () - o que não funcionou no meu caso. Você pode fazer isso @ (condição? $ "{Foo.bar}": "Padrão")
Dan Harris
6

Na maioria dos casos, a solução do CD .. funcionará perfeitamente bem. No entanto, tive uma situação um pouco mais distorcida:

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

Isso me imprimiria "& nbsp;" na minha página, respectivamente, gere a fonte &amp;nbsp;. Agora, existe uma função Html.Raw("&nbsp;")que deve permitir que você escreva o código-fonte, exceto que nesta constelação gera um erro do compilador:

Mensagem de erro do compilador: CS0173: O tipo de expressão condicional não pode ser determinado porque não há conversão implícita entre 'System.Web.IHtmlString' e 'string'

Acabei escrevendo uma declaração como a seguinte, que é menos agradável, mas funciona mesmo no meu caso:

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

Nota: o interessante é que, uma vez dentro da chave, você deve reiniciar um bloco de barbear.

Damian Vogel
fonte
Por que não apenas?@(String.IsNullOrEmpty(Model.MaidenName) ? Html.Raw("&nbsp;") : Model.MaidenName)
JP Hellemons
Uhm .. que tal por causa do erro de compilador mencionado acima? ;)
Damian Vogel
3
Desculpe, eu preciso mais café :)
JP Hellemons
1
Você pode evitar esse erro, fazendo ambos os lados do operador ternário do mesmo tipo,@(String.IsNullOrEmpty(Model.MaidenName) ? Html.Raw("&nbsp;") : Html.Raw(Model.MaidenName))
NibblyPig