简体   繁体   中英

how to bind multiselect dropdown to asp.net controller action parameter

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?

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());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM