How to create a custom HTML Helper method DropDownFor in ASP.Net MVC

asp.net-mvc c# expression-trees html-helper lambda

Question

I'm trying to create a dropdown box that will render a label under certain conditions when teh user does not have access to it.

so far I have come up with this

public static MvcHtmlString ReadOnlyCapableDropDownFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression, 
        IEnumerable<SelectListItem> selectList, 
        bool enabled, 
        object htmlAttributes
)
{
     return !enabled ? htmlHelper.DisplayFor(expression)
          : htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
}

This correctly renders a label when enabled is false and a dropdown when it is true, the issue is that the text of the label is the id of the selected select list value rather than the text that would normally show in in the dropdown.

This makes sense as I'm using the expression for the value of the display for, how do I use this expression to get the select list item text value rather than the data value?

Accepted Answer

You could compile the expression and retrieve the value from the model. Then, choose the correct text from the selectList.

TProperty val = expression.Compile().Invoke(htmlHelper.ViewData.Model);
SelectListItem selectedItem = selectList.Where(item => item.Value == Convert.ToString(val)).FirstOrDefault();
string text = "";
if (selectedItem != null) text = selectedItem.Text;

return !enabled ? new MvcHtmlString("<span>" + text + "</span>")
      : htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);

I think returning an ad-hoc MvcHtmlString should suffice in this case, since all the info you have is contained in that selectList string anyway. (It's not like your helper method has access to any data annotations, etc.)


Popular Answer

You will need to look up the text value yourself. You should be able to do it in this routine since you have the select list available:

? htmlHelper.DisplayFor(selectList.Single(x=>x.Value == expression).Text

though you might have to evaluate the expression before using it in the above code.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why