Table TagHelper for an IEnumerable Model (without using Reflection)

Viewed 897

I'm trying to create a table tag helper that can parse columns and rows from the given model automatically.

This is how it should (theoretically be used):

<table for="@Model">

</table>

and this should automatically show column names and the rows.

Generating column names wasn't that difficult since I'm passing the model

[HtmlTargetElement("table", Attributes = "for")]
public class DataTableTagHelper :TagHelper
{
    [HtmlAttributeName("for")]
    public ModelExpression For { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        foreach (var item in For.Metadata.ElementMetadata.Properties)
        {
            // generate html for theader using item.Name
        }
    }
}

But getting the values of the model isn't as easy.

Is there a way to get the values of those properties?

I'm trying to avoid reflection, because I don't think generating HTML code though reflection with every request is a good idea.

1 Answers

We get the property's value by passing the model to its property's PropertyGetter.

public override void Process(TagHelperContext context, TagHelperOutput output)
{
    foreach (var prop in For.Metadata.Properties)
    {
        var propertyName = prop.Name;
        var propertyValue = prop.PropertyGetter(For.Model);
    }

    return Task.CompletedTask;
}

If the model implements IEnumerable, then we need to pass each item to its PropertyGetter.

public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
    foreach (var item in For.Model as IEnumerable)
    {
        foreach (var prop in For.Metadata.ElementMetadata.Properties)
        {
            var name = prop.Name;
            var value = prop.PropertyGetter(item);
        }
    }

    return Task.CompletedTask;
}
Related