0

i have a html form which posts to a asp.net-mvc controller action and previously worked fine. i just added a new multiselect dropdown (using the fcbkcomplete jquery plugin) and i am having problems binding it to a new property that i just added of my binding object

i am just listing:

 <select id="SponsorIds" name="SponsorIds"></select>

in the html but it looks like fcbkcomplete somehow changes this to name="SponsorIds[]".

This is the html i get after showing "Selected Source" in the browser.

<select multiple="multiple" style="display: none;" id="SponsorIds" name="SponsorIds[]">

here is all of the html that gets spit out from the plugin

 <select multiple="multiple" style="display: none;" id="SponsorIds" name="SponsorIds[]">
<option class="selected" selected="selected" value="9">MVal</option>
</select>
<ul class="holder">
<li rel="9" class="bit-box">MVal<a href="#" class="closebutton"></a></li>
<li id="SponsorIds_annoninput" class="bit-input"><input size="1" class="maininput"    type="text"></li>
</ul>
<div style="display: none;" class="facebook-auto">
<ul style="width: 512px; display: none; height: auto;" id="SponsorIds_feed">
<li class="auto-focus" rel="9"><em>MVal</li></ul><div style="display: block;" class="default">Type Name . . .
</div>
</div>

and here is my controller action:

 public ActionResult UpdateMe(ProjectViewModel entity)
    {
    }

The view model, ProjectViewModel has a property:

   public int[] SponsorIds { get; set; }

which i thought would bind fine to this but doesn't seem to as it just shows up as "null" on the serverside. Can anyone see anything wrong here?

leora
  • 188,729
  • 360
  • 878
  • 1,366

1 Answers1

2

A correctly named list box (in terms of what the default ASP.NET MVC model binder can cope with) would be:

name="SponsorIds"

and not:

name="SponsorIds[]"

at least if you expect to bind this back to int[] with the default model binder. And that's what the Html.ListBoxFor helper generates. Example:

@Html.ListBoxFor(
    x => x.SponsorIds, 
    new SelectList(
        new[] { 
            new { Value = "1", Text = "MVal1" },
            new { Value = "2", Text = "MVal2" }, 
            new { Value = "3", Text = "MVal3" }, 
        }, 
        "Value", "Text"
    )
)

emits:

<select id="SponsorIds" multiple="multiple" name="SponsorIds">
    <option value="1">MVal1</option>
    <option value="2">MVal2</option>
    <option value="3">MVal3</option>
</select>

and the model binder is happy.


UPDATE:

You could also have a custom model binder capable of parsing this:

public class FCBKCompleteIntegerArrayModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "[]");
        if (values != null && !string.IsNullOrEmpty(values.AttemptedValue))
        {
            // TODO: A minimum of error handling would be nice here
            return values.AttemptedValue.Split(',').Select(x => int.Parse(x)).ToArray();
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}

and then register this binder in Application_Start:

protected void Application_Start()
{
    ...
    ModelBinders.Binders.Add(typeof(int[]), new FCBKCompleteIntegerArrayModelBinder());
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • i am listing it as name="SponsorIds" but i seems like fcbkcomplete changes this to be name="SponsorIds[]". i can't figure out why they would do this. Given that this is out of my control, any suggestions ?? i editted the question to clarity that fcbkcomplete was adding the [] to my select name attribute – leora Feb 21 '11 at 21:59
  • 1
    @ooo, that's one of the situations where you could curse at the plugin authors for not allowing you a way to specify the name of the field (or have they? did you read the doc by the way?). Well, I can see at least two possible workarounds: 1. Write a custom model binder (see my UPDATE for this) or 2. Subscribe for the `submit` event of your form and perform voodoo magic with jquery to rename this field to make the default model binder happy. – Darin Dimitrov Feb 21 '11 at 22:16
  • i found another "hack" here: http://hypertrends.com/net/2010/03/11/facebook-style-autocomplete-using-asp-net-mvc-and-fcbkcomplete/ where you grab this one field from Request.Form directly. this link actually brings up the same point on how its ridiculous that fcbkcomplete adds the [] to the attribute – leora Feb 22 '11 at 02:01