28

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.

fearofawhackplanet
  • 52,166
  • 53
  • 160
  • 253

4 Answers4

56

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)
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • No that doesn't work either (prints the   string). I like the idea of html helper. (Its also easy in the view using an if/else statement). I was curious to figure out the syntax as a learning exercise though as I'm quite new to Razor. – fearofawhackplanet Jul 28 '11 at 10:18
  • 1
    @fearofawhackplanet, this should work. You must have forgotten something. Did you notice the `Html.Raw` in the beginning of my expression? It is because of using Html.Raw in the beginning that you must ensure to properly HTML encode the string in the case when it is not empty. – Darin Dimitrov Jul 28 '11 at 11:06
  • Ah... uh that's weird. I just double checked it and you are correct, it works. It didn't seem to work yesterday, I must have had a typo somewhere I guess. Thanks! – fearofawhackplanet Jul 29 '11 at 10:58
  • Gah, thank you, Darin. I was putting the Html.Raw() on one side of the ternary, which kept causing issues. Didn't even think of putting it outside. SMH. – John Washam May 09 '14 at 19:20
1

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.

yoel halb
  • 12,188
  • 3
  • 57
  • 52
0

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>
Dalton Pearson
  • 540
  • 3
  • 9
-1
@(string.IsNullOrEmpty(myString)? ":&nbsp;": myString)
ek_ny
  • 10,153
  • 6
  • 47
  • 60