Home > Enterprise >  C# Web API: Iterating Array and Append to HTML table
C# Web API: Iterating Array and Append to HTML table

Time:09-27

I am trying to create a POST endpoint where on success, it will send an HTML email with the POST data. I am struggling trying to iterate over the JSON array of objects and appending that data to a HTML table.

JSON data:

{
   "Submitter":[
      {
         "Obj1":[
            "test",
            "test2"
         ]
      },
      {
         "Obj2":[
            "test3",
            "test4"
         ]
      }
   ]
}

TestingController:

    public class Testing2Controller : ControllerBase
    {
        public class Submitter
        {
            public List<string> Obj1 { get; set; }
            public List<string> Obj2 { get; set; }
        }

        public class MyData
        {
            public List<Submitter> Submitter { get; set; }
        }

        public string POST([FromBody] MyData data)
        {

            string composeTableObj1 = @"";
            string composeTableObj2 = @"";


            foreach (var item in data.Submitter)
            {
                composeTableObj1  = $"<tr>"; //start row tag
            //Column 1 Obj1 data
            if (item.Obj1 != null)
                {
                    foreach (var objItem in item.Obj1)
                    {
                        composeTableObj1  = $"<td>{objItem}</td>";
                    }
                }

                //Column 2 Obj2 data
                if (item.Obj2 != null)
                {

                    foreach (var objItem in item.Obj2)
                    {
                        composeTableObj1  = $"<td>{objItem}</td>";
                    }
                }
                composeTableObj1  = $"</tr>"; //end row tag


        }

            string body = @$"<table>
<thead>
<tr>
    <th>Object 1</th>
    <th>Object 2</th>
</tr>
</thead>
<tbody>
{composeTableObj1}
</tbody>
</table>
";

            return body;
        }
    }

The above code gives me the following undesired result:

| Object 1 | Object 2 |
|----------|----------|
| test     | test2    |
| test3    | test4    |

This is the desired result I'm after:

| Object 1 | Object 2 |
|----------|----------|
| test     | test3    |
| test2    | test4    |

Been stuck on this for quite some time, TIA!

CodePudding user response:

Looks like your HTML is a bit off - writing HTML like this can be tedious. I am guessing based off of the hard coded table headers in the HTML and the structure of the Submitter class that you will only ever have two Objn items in your JSON. If this is true, you can ditch the foreach loop for a for loop, and get the value out of data.Submitter[n] using the loops iterator:

public string Post([FromBody] MyData data)
{
    string composeTableObj = ""; 

    for (int i = 0; i < data.Submitter.Count(); i  )
    {
        composeTableObj  = $"<tr>"; //start row tag
        composeTableObj  = $"<td>{data.Submitter[0].Obj1[i]}</td>";
        composeTableObj  = $"<td>{data.Submitter[1].Obj2[i]}</td>";
        composeTableObj  = $"</tr>"; //end row tag
    }

    return @$"<table><thead><tr><th>Object 1</th><th>Object 2</th></tr></thead><tbody>{composeTableObj}</tbody></table>";
}

Returned HTML:

<table><thead><tr><th>Object 1</th><th>Object 2</th></tr></thead><tbody><tr><td>test</td><td>test3</td></tr><tr><td>test2</td><td>test4</td></tr></tbody></table>

Rendered:

html

Obviously, this isn't very dynamic. If you find you need more Objn, you'll need to update the Submitter class, and you will have to add to the code within the loop (and add another header for your HTML).


If you have more items in the Obj arrays, you can do the following:

public string Post([FromBody] MyData data)
{
    string composeTableObj = "";

    int obj1Count = data.Submitter[0].Obj1.Count;
    int obj2Count = data.Submitter[1].Obj2.Count;

    int loopCount = obj1Count >= obj2Count ? obj1Count : obj2Count;

    for (int i = 0; i < loopCount; i  )
    {
        string obj1String = obj1Count <= i ? " " : data.Submitter[0].Obj1[i];
        string obj2String = obj2Count <= i ? " " : data.Submitter[1].Obj2[i];

        composeTableObj  = $"<tr>"; //start row tag
        composeTableObj  = $"<td>{obj1String}</td>";
        composeTableObj  = $"<td>{obj2String}</td>";
        composeTableObj  = $"</tr>"; //end row tag
    }

    return  @$"<table><thead><tr><th>Object 1</th><th>Object 2</th></tr></thead><tbody>{composeTableObj}</tbody></table>";
}

This first gets the greater of the two .Counts between your Obj lists to set the loops condition, and then performs an index bounds check. If the objnCount is less than or equal to i, set it to a space, otherwise take the value for its respective Obj list. With 6 items in Obj2 and only 2 items in Obj1, the HTML looked like this:

rendered html with more objs

  • Related