Search code examples
c#razorstringbuilder

C# StringBuilder AppendFormat throwing System.FormatException


I have this method below which I've simplified to reproduce the problem, can anyone explain why the system format exception is thrown?

I have tried adding the @ to the beginning of the format string in-case it was a problem with escape characters but it didn't help.

private void doThing(StringBuilder builder, string inPrimaryKey) {
    // At this point the builder.ToString() results in "            <div  class="v-group width-100 shadowed OrderPanel"
    // and inPrimaryKey is "OrderId"

    // Throws System.FormatException with the detail "Input string was not in a correct format."
    builder.AppendFormat(@" @if (Model.{0} > 0) { <text>StateNonEditable</text> } else { <text>StateEditable</text> }", inPrimaryKey);
}

A bit of background, we're using this code to generate a cshtml page for use in a web app so the stringbuilder initially contains some html and then we are adding some C# MVC Razor within the format section.


Solution

  • can anyone explain why the system format exception is thrown?

    Yes: your format string includes this:

    { <text>StateNonEditable</text> }
    

    That's not a valid format item. You need to escape the braces that aren't meant to be part of a format item by doubling them:

    builder.AppendFormat(
        " @if (Model.{0} > 0) {{ <text>StateNonEditable</text> }} else {{ <text>StateEditable</text> }}",
        inPrimaryKey);
    

    Alternatively, just call AppendFormat once and then Append once:

    builder.AppendFormat(" @if (Model.{0} > 0 ", inPrimaryKey)
           .Append("{ <text>StateNonEditable</text> } else { <text>StateEditable</text> }");
    

    That's probably a more readable solution, to be honest.