0

.NET MVC HtmlHelper extension

I have this custom HtmlHelper extension, it gets a lambda expression that must be a child collection of the model, (for example model.childs), and a string that contains the name of a property of the collection items (for example "child_name") And it creates a <span> whose content is the concatenation of the value of that property on every item of the collection. (for example "-- Mary -- Paul -- Rick")

public static MvcHtmlString SpanCollectionFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TValue>>> expression, string nomPropToUse, IDictionary<string, object> htmlAttributes) 
{

    var collection = expression.Compile()(html.ViewData.Model).ToList();

    string text = "";
    if (collection != null) {
        foreach (var ent in collection) {
            var val = ent.GetType().GetProperty(nomPropToUse).GetValue(ent, null).ToString();
            text += " -- " + val;
        }
    }

    //creates span using tagbuilder
    var span = new TagBuilder("span");
    span.SetInnerText(text);
    span.MergeAttributes(new RouteValueDictionary(htmlAttributes));

    return MvcHtmlString.Create(span.ToString());
}

That I can use in a Razor view like:

Html.SpanCollectionFor(modelItem => item.childs, "child_name")

So this creates a <span> whose content is the concatenation of the name of every child in the collection.

This is working, but I have 2 problems:

First problem: This works for simple cases, where the nomPropToUse is a property of the collection items. but wont work if I try to pass a property of a granchild. so for example, imagine that every child contains a child Type, with a property type_name. I would use it with:

Html.SpanCollectionFor(modelItem => item.childs, "type.type_name")

but this does not work.

Second problem: I would like to have also an overload that receives the second parameter as a lambda expression too, instead of a string. something like

public static MvcHtmlString SpanCollectionFor<TModel, TValue, KValue>(this HtmlHelper<TModel> html, 
    Expression<Func<TModel, IEnumerable<TValue>>> expression, 
    Expression<Func<TModel, KValue>> expression2, 
    IDictionary<string, object> htmlAttributes) 
{

Any help?

patsy2k
  • 471
  • 2
  • 8
  • `SpanCollectionFor` and `BadgeCollectionFor` are the same? – Chetan Jul 02 '21 at 02:25
  • 1
    The problem will be solved by itself when you use expressions and not string parameters. The use of reflections for nested properties is possible but not optimal – benuto Jul 02 '21 at 09:43
  • @ChetanRanpariya: ops, yes. That was an error when writing the question, thanks for noticing. I did edit the question. – patsy2k Jul 04 '21 at 19:53

0 Answers0