Question

I have a mvc web project where I try to render a list of checkbox with the EditorFor extension method but the result just display the ids as text instead of of a list of checkbox.

Here is the code in the view:

  <div id="permissions" class="tab-body">
     @Html.Label("Permissions :")
     @Html.EditorFor(x => Model.Permissions)
     <br />
     <br />
  </div>

This is the property 'Permissions' of the object 'Model':

  [DisplayName("Permissions")]
  public List<PermissionViewModel> Permissions { get; set; }

And this is the PermissionViewModel:

public class PermissionViewModel { public int Id { get; set; }

  public UserGroupPermissionType Name { get; set; }

  public string Description { get; set; }

  public bool IsDistributable { get; set; }

  public bool IsGranted { get; set; }

}

And finally, this is the result in the browser:

<div id="permissions" class="tab-body" style="display: block;">
<label for="Permissions_:">Permissions :</label>
192023242526272829
<br>
<br>
</div>

Have you any idea why the html is not generated correctly? Missing dependencies? Conflict in dependencies? Web.Config configured not correctly?

Thank you very much for you help.

Was it helpful?

Solution

It looks as if you need to create an editor template for the "PermissionViewModel" class, as right now, MVC seems to be confused with how to make an editor for such a complex object.

In the folder where the view is being served from, add a folder called "EditorTemplates"

Then add a new partial view in that folder. The code should be:

@model IEnumberable<PermissionViewModel>
@foreach(var permission in Model)
@Html.EditorFor(x => x.Name)
@Html.EditorFor(x => x.Description)
@Html.EditorFor(x => x.IsDistributable)
@Html.EditorFor(x => x.IsGranted)

You will need to create an Editor Template for the Name class as well.

So now in your view you can call

<div id="permissions" class="tab-body">
 @Html.Label("Permissions :")
 @Html.EditorFor(x => Model.Permissions)
 <br />
 <br />
</div>

And MVC will know to use the editor template you just made for your permission.

A good resource for learning about editor templates is here: http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

OTHER TIPS

Maybe you want to make something yourself?

    public delegate object Property<T>(T property);

    public static HtmlString MultiSelectListFor<TModel, TKey, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, IEnumerable<TKey>>> forExpression,
        IEnumerable<TProperty> enumeratedItems,
        Func<TProperty, TKey> idExpression,
        Property<TProperty> displayExpression,
        Property<TProperty> titleExpression,
        object htmlAttributes) 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(TProperty);

        //check for problems
        if (enumeratedItems == null) throw new ArgumentNullException("The list of items cannot be null");

        //build the select tag
        var returnText = string.Format("<select multiple=\"multiple\" 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 (TProperty 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 (propertyValue.Contains(idValue))
            {
                returnText += " selected=\"selected\"";
            }
            returnText += string.Format(">{0}</option>\n", HttpUtility.HtmlEncode(displayValue));
        }

        //close the select tag
        returnText += "</select>";
        return new HtmlString(returnText);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top