Html literal in Razor ternary expression

2019-03-17 08:45发布

问题:

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.

回答1:

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)


回答2:

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.



回答3:

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