I suspect that the problem comes from the fact that you haven't set the traditional
parameter and jQuery doesn't send the collection in a format that the default model binder is able to understand. If you are using jQuery 1.4 or later you must set this parameter.
For example:
Model:
public class MyViewModel
{
public string[] SelectedValues { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Items = new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
new SelectListItem { Value = "4", Text = "item 4" },
}
};
return View(model);
}
public ActionResult GetCS(string[] values)
{
return Json(new
{
message = string.Format("{0} item(s) selected", values.Length)
}, JsonRequestBehavior.AllowGet);
}
}
View:
@model MyViewModel
@Html.ListBoxFor(
x => x.SelectedValues,
Model.Items,
new {
id = "mylist",
}
)
@Html.ActionLink("Send AJAX", "getcs", null, new { id = "mylink" })
Script:
$(function () {
$('#mylink').click(function () {
var selectedValues = $('#mylist').val();
$.getJSON(this.href, $.param({ values: selectedValues }, true), function (result) {
alert(result.message);
});
return false;
});
});
Notice how I use the $.param
function and pass it true as second argument which represents the traditional parameter. Try with calling it with true
and false
and you will see the differences in FireBug and you will understand why it doesn't work if you don't set this parameter.
You could also set this parameter globally for all AJAX requests:
$.ajaxSetup({
traditional: true
});
and then the following will work:
$.getJSON(this.href, { values: selectedValues }, function (result) {
alert(result.message);
});