Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6764675
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T14:37:18+00:00 2026-05-26T14:37:18+00:00

I wrote an HtmlHelper expression I use a lot of the time to put

  • 0

I wrote an HtmlHelper expression I use a lot of the time to put title tags into my dropdown lists like so:

    public static HtmlString SelectFor<TModel, TProperty, TListItem>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        IEnumerable<TListItem> enumeratedItems,
        string idPropertyName,
        string displayPropertyName,
        string titlePropertyName,
        object htmlAttributes) where TModel : class
    {
        //initialize values
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var propertyName = metaData.PropertyName;
        var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();
        var enumeratedType = typeof(TListItem);

        //build the select tag
        var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
        if (htmlAttributes != null)
        {
            foreach (var kvp in htmlAttributes.GetType().GetProperties()
             .ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
            {
                returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
                 HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
            }
        }
        returnText += ">\n";

        //build the options tags
        foreach (TListItem listItem in enumeratedItems)
        {
            var idValue = enumeratedType.GetProperties()
             .FirstOrDefault(p => p.Name == idPropertyName)
             .GetValue(listItem, null).ToStringOrEmpty();
            var titleValue = enumeratedType.GetProperties()
             .FirstOrDefault(p => p.Name == titlePropertyName)
             .GetValue(listItem, null).ToStringOrEmpty();
            var displayValue = enumeratedType.GetProperties()
             .FirstOrDefault(p => p.Name == displayPropertyName)
             .GetValue(listItem, null).ToStringOrEmpty();
            returnText += string.Format("<option value=\"{0}\" title=\"{1}\"",
             HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
            if (idValue == propertyValue)
            {
                returnText += " selected=\"selected\"";
            }
            returnText += string.Format(">{0}</option>\n", displayValue);
        }

        //close the select tag
        returnText += "</select>";
        return new HtmlString(returnText);
    }

…this works swimmingly, but there are times when I want to go further. I’d like to customize the id, display, and title pieces of this beast without having to write out the html. For example, if I have some classes in a model like so:

public class item
{
    public int itemId { get; set; }
    public string itemName { get; set; }
    public string itemDescription { get; set; }
}

public class model
{
    public IEnumerable<item> items { get; set; }
    public int itemId { get; set; }
}

In my view I can write:

@Html.SelectFor(m => m.itemId, Model.items, "itemId", "itemName", "itemDescription", null)

…and I’ll get a nice dropdown with title attributes etc. This is great as long as the enumerated items have properties exactly as I’d like to display them. But what I’d really like to do is something like:

@Html.SelectFor(m => m.itemId, Model.items, id=>id.itemId, disp=>disp.itemName, title=>title.itemName + " " + title.itemDescription, null)

…and have, in this case, the title attribute on the options be a concatenation of the itemName property and the itemDescription property. I confess the meta-level of lambda expressions and Linq functions has got me a little dizzy. Can someone point me in the right direction?

FINAL RESULT For those who are curious, the following code gives me complete control over the select list’s ID, Title, and DisplayText properties using lambda expressions:

    public static HtmlString SelectFor<TModel, TProperty, TListItem>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> forExpression,
        IEnumerable<TListItem> enumeratedItems,
        Attribute<TListItem> idExpression,
        Attribute<TListItem> displayExpression,
        Attribute<TListItem> titleExpression,
        object htmlAttributes,
        bool blankFirstLine) where TModel : class
    {
        //initialize values
        var metaData = ModelMetadata.FromLambdaExpression(forExpression, htmlHelper.ViewData);
        var propertyName = metaData.PropertyName;
        var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();
        var enumeratedType = typeof(TListItem);

        //build the select tag
        var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
        if (htmlAttributes != null)
        {
            foreach (var kvp in htmlAttributes.GetType().GetProperties()
             .ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
            {
                returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
                 HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
            }
        }
        returnText += ">\n";

        if (blankFirstLine)
        {
            returnText += "<option value=\"\"></option>";
        }

        //build the options tags
        foreach (TListItem listItem in enumeratedItems)
        {
            var idValue = idExpression(listItem).ToStringOrEmpty();
            var displayValue = displayExpression(listItem).ToStringOrEmpty();
            var titleValue = titleExpression(listItem).ToStringOrEmpty();
            returnText += string.Format("<option value=\"{0}\" title=\"{1}\"",
                HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
            if (idValue == propertyValue)
            {
                returnText += " selected=\"selected\"";
            }
            returnText += string.Format(">{0}</option>\n", displayValue);
        }

        //close the select tag
        returnText += "</select>";
        return new HtmlString(returnText);
    }

    public delegate object Attribute<T>(T listItem);
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T14:37:19+00:00Added an answer on May 26, 2026 at 2:37 pm

    If you don’t need the title attribute on individual options your code could be simplified to:

    public static HtmlString SelectFor<TModel, TProperty, TIdProperty, TDisplayProperty, TListItem>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        IEnumerable<TListItem> enumeratedItems,
        Expression<Func<TListItem, TIdProperty>> idProperty,
        Expression<Func<TListItem, TDisplayProperty>> displayProperty,
        object htmlAttributes
    ) where TModel : class
    {
        var id = (idProperty.Body as MemberExpression).Member.Name;
        var display = (displayProperty.Body as MemberExpression).Member.Name;
        var selectList = new SelectList(enumeratedItems, id, display);
        var attributes = new RouteValueDictionary(htmlAttributes);
        return htmlHelper.DropDownListFor(expression, selectList, attributes);
    }
    

    and used like this:

    @Html.SelectFor(
        m => m.itemId, 
        Model.items, 
        id => id.itemId, 
        disp => disp.itemName, 
        null
    )
    

    And if you need the title attribute, well, you will have to implement everything that the DropDownList helper does manually which could be quite of a pain. Here’s an example of only a small portion of all the functionality:

    public static class HtmlExtensions
    {
        private class MySelectListItem : SelectListItem
        {
            public string Title { get; set; }
        }
    
        public static HtmlString SelectFor<TModel, TProperty, TIdProperty, TDisplayProperty, TListItem>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression,
            IEnumerable<TListItem> enumeratedItems,
            Expression<Func<TListItem, TIdProperty>> idProperty,
            Expression<Func<TListItem, TDisplayProperty>> displayProperty,
            Func<TListItem, string> titleProperty,
            object htmlAttributes
        ) where TModel : class
        {
            var name = ExpressionHelper.GetExpressionText(expression);
            var fullHtmlName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    
            var select = new TagBuilder("select");
            var compiledDisplayProperty = displayProperty.Compile();
            var compiledIdProperty = idProperty.Compile();
            select.GenerateId(fullHtmlName);
            select.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            select.Attributes["name"] = fullHtmlName;
            var selectedValue = htmlHelper.ViewData.Eval(fullHtmlName);
            var options = 
                from i in enumeratedItems
                select ListItemToOption(
                    ItemToSelectItem(i, selectedValue, compiledIdProperty, compiledDisplayProperty, titleProperty)
                );
            select.InnerHtml = string.Join(Environment.NewLine, options);
            return new HtmlString(select.ToString(TagRenderMode.Normal));
        }
    
        private static MySelectListItem ItemToSelectItem<TListItem, TIdProperty, TDisplayProperty>(TListItem i, object selectedValue, Func<TListItem, TIdProperty> idProperty, Func<TListItem, TDisplayProperty> displayProperty, Func<TListItem, string> titleProperty)
        {
            var value = Convert.ToString(idProperty(i));
            return new MySelectListItem
            {
                Value = value,
                Text = Convert.ToString(displayProperty(i)),
                Title = titleProperty(i),
                Selected = Convert.ToString(selectedValue) == value
            };
        }
    
        private static string ListItemToOption(MySelectListItem item)
        {
            var builder = new TagBuilder("option");
            builder.Attributes["value"] = item.Value;
            builder.Attributes["title"] = item.Title;
            builder.SetInnerText(item.Text);
            if (item.Selected)
            {
                builder.Attributes["selected"] = "selected";
            }
            return builder.ToString();
        }
    }
    

    and then use like this:

    @Html.SelectFor(
        m => m.itemId, 
        Model.items, 
        id => id.itemId, 
        disp => disp.itemName, 
        title => title.itemName + " " + title.itemDescription, 
        null
    )
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I wrote an HtmlHelper and I'm wondering where I should put it in my
This throws error: public static void RenderPartialForEach<T> (this HtmlHelper helper, string partialName, IList<T> list)
I wrote a Flickr search engine that makes a call to either a public
I'm trying to write an extension for DropDownListFor : public static MvcHtmlString DropDownListFor<TModel, TProperty>(this
I have a utility method that uses Display Templates to generate HTML: public static
i have wrote a extension method for customize my validation messages, like this: namespace
I wrote a custom HtmlHelper to apply... class = active to a menu item
Wrote a script in bash. Now im need to bring information into a text
Is it possible to use HtmlHelper in a controller, for-example to get the TextBox(...)
Wrote a quick Java proggy to spawn 10 threads with each priority and calculate

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.