One line IF in Blazor not outputting correct

Viewed 49

I am trying to use the following code.

<td>@(piece.Publisher == null ? (MarkupString)"<span class='badge bg-danger'>No</span>" : piece.Publisher.Name)</td>

It's not producing what I'm intending. It's literally printing 'No' in the TD.

How can I get it to render the span as HTML?

--UPDATE-- It's odd, I've tried both suggestions and breaking it out in to fill IF statements seems to be the most reliable, but here is an instance where it works fine.

<p>Score?: @(piece.ScoreYesNo ? (MarkupString)"<span class='badge bg-success'>Yes</span>" : (MarkupString)"<span class='badge bg-danger'>No</span>")</p>

Now if I do the same thing with Publisher, it renders the markup as a string.

<p>Publisher: @(piece.Publisher == null ? ((MarkupString)"<span class='badge bg-danger'>No</span>") : piece.Publisher.Name)</p>

Notice that the one that works has MarkupString in both the true and false, It's strange. Anyone understand why it's not working?

Thanks!

1 Answers

Anyone understand why it's not working?

The base problem is the C# rule that in x = c ? a : b; the a and b expressions must be 'assignment compatible' with x.

<td>@(piece.Publisher == null 
   ? (MarkupString)"<span class='badge bg-danger'>No</span>" 
   : piece.Publisher.Name)</td>

You have here the schema c ? MarkupString : string and string and MarkupString are not assignment compatible with each other. It is not obvious that this code would compile at all but it works (ie, no errors) in C#9 and later because the compiler finds a loophole in this overload in RenderTreeBuilder:

void AddContent(int sequence, object? textContent)

So the MarkupString is first cast to object and then rendered with ToString(), defeating the whole purpose of MarkupString.

Your second sample with c ? (MarkupString)"a" : (MarkupString)"b" works because both expressions now return a MarkupString.

A shorter notation would be @(new MarkupString(c ? a : b)) but be sure that both a and b do not expose you to HTML injection. Publisher.Name is probably not safe in that regard.

Related