RemoteAttribute没有将查询字符串作为IEnumerable <t>正确传递</t>

时间:2013-12-06 03:52:29

标签: c# jquery asp.net-mvc-4

假设我有一个像这样的ViewModel:

public class Foo
{
    public int Id { get; set; }

    public IEnumerable<SelectListItem> AvailableBars { get; set; } /* For populating DropDownList */

    [Remote("CheckIds", "Baz", AdditionalFields = "Id")]
    public IEnumerable<int> BarIds { get; set; }
}

这样的控制器:

public class BazController
{
    // ...CRUD operations skipped

    public ActionResult CheckIds(int id, IEnumerable<int> barIds)
    {
        bool isValid = /* Logic for checking validity */
        if (!isValid)
        {
            return Json("Error", JsonRequestBehavior.AllowGet);
        }

        return Json(true, JsonRequestBehavior.AllowGet);
    }
}

在我看来:

@Html.DropDownListFor(model => model.BarIds, Model.AvailableBars, new { multiple = "multiple" })

问题是当我尝试触发验证时,实际的HTTP GET请求变为:

http://localhost:8080/Baz/CheckIds?id=4&barIds=7%2C8 /* <-- barIds=7,8 */

而不是:

http://localhost:8080/Baz/CheckIds?id=4&barIds=7&barIds=8

默认模型绑定器无法将int绑定到IEnumerable<int>。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

jquery.validate和jquery.validate.unobstrusive不处理数组。 如果你真的需要处理数组,你需要修改它们。

我能想到的最短的解决方案:

1)将$.ajax remote来自jquery.validate的{​​{1}}来电修改为此

var ajaxOptions = $.extend(true, {
    url: param,
    mode: "abort",
    port: "validate" + element.name,
    dataType: "json",
    data: data,
    success: function (response) {
        ...
    }
}, param);

//Fix the bug
//we are not supposed to pass functions to data parameter
//capture the function output so array values are
//serialized properly
$.each(ajaxOptions.data, function (key, value) {
    if ($.isFunction(value)) {
        ajaxOptions.data[key] = value();
    }
});

$.ajax(ajaxOptions);

2)将traditional: true添加到remote

jquery.validate.unobstrusive适配器
var value = {
    url: options.params.url,
    type: options.params.type || "GET",
    data: {},
    traditional: true //so that MVC is able to de-serialize arrays
}