If you bind comma separated value (CSV) a lot, the easiest and maintainable way is to create a custom model binder called CommaSeparatedModelBinder.
It is not common to capture select's change event, and make an Ajax call whenever user selects an option. But it is up to you.


[HttpGet]
public ActionResult RetournerPostes()
{
return View();
}
[HttpPost]
public ActionResult RetournerPostes(string avion,
[ModelBinder(typeof(CommaSeparatedModelBinder))] int[] types)
{
return View();
}
View
@using (Html.BeginForm())
{
<select id="opt1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="opt2" multiple>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<input type="submit" value="Submit"/>
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$('select#opt2').change(function () {
var data = JSON.stringify({ avion: $('select#opt1').val(), types: $('select#opt2').val() });
console.log(data);
$.ajax({
url: '@Url.Action("RetournerPostes", "Home")',
data: data,
type: 'POST',
contentType: "application/json",
dataType: 'JSON',
success: function(msg) {
console.log(msg);
}
});
});
</script>
CommaSeparatedModelBinder
public class CommaSeparatedModelBinder : DefaultModelBinder
{
private static readonly MethodInfo ToArrayMethod = typeof(Enumerable).GetMethod("ToArray");
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return BindCsv(bindingContext.ModelType, bindingContext.ModelName, bindingContext)
?? base.BindModel(controllerContext, bindingContext);
}
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
{
return BindCsv(propertyDescriptor.PropertyType, propertyDescriptor.Name, bindingContext)
?? base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
}
private object BindCsv(Type type, string name, ModelBindingContext bindingContext)
{
if (type.GetInterface(typeof(IEnumerable).Name) != null)
{
var actualValue = bindingContext.ValueProvider.GetValue(name);
if (actualValue != null)
{
var valueType = type.GetElementType() ?? type.GetGenericArguments().FirstOrDefault();
if (valueType != null && valueType.GetInterface(typeof(IConvertible).Name) != null)
{
var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(valueType));
foreach (var splitValue in actualValue.AttemptedValue.Split(new[] { ',' }))
{
if (!String.IsNullOrWhiteSpace(splitValue))
list.Add(Convert.ChangeType(splitValue, valueType));
}
if (type.IsArray)
return ToArrayMethod.MakeGenericMethod(valueType).Invoke(this, new[] { list });
return list;
}
}
}
return null;
}
}
Original Source: CommaSeparatedModelBinder.cs
val()returns an array formultiple. However output of$('select#opt2').val()seems to bestringtry to convert it to array. trytypes: $('select#opt2').val().split(',')once