fearofawhackplanet
fearofawhackplanet

Reputation: 53378

Html literal in Razor ternary expression

I'm trying to do something like the following

<div id="test">
    @(
        string.IsNullOrEmpty(myString)
          ? @:&nbsp;
          : myString   
    )
</div>

The above syntax is invalid, I've tried a bunch of different things but can't get it working.

Upvotes: 28

Views: 19462

Answers (4)

Dalton Pearson
Dalton Pearson

Reputation: 570

Another updated approach thanks to new features is to create a helper function right in the view. This has the advantage of making the syntax a little cleaner especially if you are going to be calling it more than once. This is also safe from cross site scripting attacks without the need to call @Html.Encode() since it doesn't rely on @Html.Raw().

Just put the following right into your view at the very top:

@helper NbspIfEmpty(string value) {
  if (string.IsNullOrEmpty(value)) {
    @:&nbsp;
  } else {
    @value
  }
}

Then you can use the function like this:

<div id="test">
    @NbspIfEmpty(myString)
</div>

Upvotes: 0

yoel halb
yoel halb

Reputation: 12711

You could do:

@{
   Func<dynamic, object> a = (true ? 
        (Func<dynamic, object>)(@<text> Works1 </text>) 
        : (Func<dynamic, object>)(@<text> Works2 </text>));
   @a(new object());
}

Or to make it inline do:

@(
  ((Func<dynamic, object>)(true == false 
      ? (Func<dynamic, object>)(@<text> Works2 </text>) 
      : (Func<dynamic, object>)(@<text> Works3 </text>)))
   (new object())
 )

(Note that all of the above will work one line as well, I have just separated them for clarity)

However the original intention of the OP can alos be modified to work, but this time line breaks must be preserved:

@(((Func<dynamic, object>)( true == true ? (Func<dynamic,object>)(@: Works
): (Func<dynamic, object>)(@: Not Works
)))("").ToString())

Note

In fact you need the cast only on one of the options in the operator, and also you don't have to give dynamic as the first option to Func, you can give just anything, and the same when evaluating you can give anything as long it matches the first argument to Func.

For example you can do the following (which I think is the shortest version):

    @(
      ((Func<int, object>)(true == false 
          ? (Func<int, object>)(@<text> Works2 </text>) 
          : @<text></text>))
       (0)
     )

If you use it a lot, it would be a good idea to inherit Func as in

public class Razor : Func<dynamic, object>{}

Or one can even write a wrapper method (or even a lambda expression in which case [I am not sure but it might be possible] to use a regular ternary operator and defer the cast to the callee) for the ternary operator.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

Try the following:

@Html.Raw(string.IsNullOrEmpty(myString) ? "&nbsp;" : Html.Encode(myString))

But I would recommend you writing a helper that does this job so that you don't have to turn your views into spaghetti:

public static class HtmlExtensions
{
    public static IHtmlString ValueOrSpace(this HtmlHelper html, string value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return new HtmlString("&nbsp;");
        }
        return new HtmlString(html.Encode(value));
    }
}

and then in your view simply:

@Html.ValueOrSpace(myString)

Upvotes: 56

ek_ny
ek_ny

Reputation: 10243

@(string.IsNullOrEmpty(myString)? ":&nbsp;": myString)

Upvotes: -1

Related Questions