1

I have an applicant model that contains a list of tags:

public class Applicant
{
    public virtual IList<Tag> Tags { get; protected set; }
}

When the form is submitted, there is an input field that contains a comma-delimited list of tags the user has input. I have a custom model binder to convert this list to a collection:

public class TagListModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var incomingData = bindingContext.ValueProvider.GetValue("tags").AttemptedValue;
        IList<Tag> tags = incomingData.Split(',').Select(data => new Tag { TagName = data.Trim() }).ToList();
        return tags;
    }
}

However, when my model is populated and passed into the controller action on POST, the Tags property is still an empty list. Any idea why it isn't populating the list correctly?

Stefan Bossbaly
  • 6,682
  • 9
  • 53
  • 82
arknotts
  • 454
  • 3
  • 13

3 Answers3

2

A model binder only binds submitted values. It does not bind values rendered in the view.

You need to create a custom EditorTemplate to render the tags as you need them.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
2

The problem is you have the protected set accessor in Tags property. If you change that into public as below things will work fine.

public class Applicant
{
    public virtual IList<Tag> Tags { get; set; }
}
VJAI
  • 32,167
  • 23
  • 102
  • 164
1

MVC can already bind to a List, I would recommend using the built in technology that already does what you need.

I didn't notice any code about adding the binder, did you add your ModelBinder to the Binders?

protected void Application_Start()
{
  ModelBinders.Binders.Add(typeof(IList<Tag>), new TagListModelBinder());
}
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • Yes, I did add it to the binders and it's being called. It just doesn't get populated in the action method parameter. – arknotts Jun 28 '12 at 16:55
  • I looked at your link about binding to a list. Unfortunately this won't work in my scenario since the javascript I use on the client side puts everything into one input field. – arknotts Jun 28 '12 at 18:08