将knockout.js的observablearray对象传递给MVC控制器操作?

14

我正在使用knockout和MVC。我想将一个可观察的对象数组从knockout传回我的MVC控制器动作,以保存到数据库中。如果我通过ko.toJSON(viewModel.ArrayName)将数组从knockout传递到我的控制器动作,它在我的控制器参数中返回null。如果我尝试通过ko.toJS(viewModel.ArrayName)将其传递到MVC,它具有正确的项目数量,但由于某种原因数据为null。如何实现这一点的任何帮助都将不胜感激。谢谢!

我使用的jQuery数据检索方法:

var dataService = {};
var viewModel;

$(document).ready(function () {
    dataService.getAccessLevelList();
})

dataService.getAccessLevelList = function () {
    $.post('/DataService/GetAccessLevelList', null, function (data) {
        viewModel = ko.mapping.fromJS(data); 
        ko.applyBindings(viewModel);
    });
}

这是有问题的方法:

updateAccessLevels = function () {
    $.post('/DataService/UpdateAccessLevels', { accessLevels: ko.toJSON(viewModel.AccessLevels) }, function (status) {
        alert(status);
    });
}

我的MVC控制器数据检索操作:

    [HttpPost]
    public ActionResult GetAccessLevelList()
    {
        FacilityAccessViewModel viewModel = new FacilityAccessViewModel();
        viewModel.AccessLevels = unitOfWork.AccessLevelRepository.Get().ToList();
        return Json(viewModel);
    }

当尝试从Knockout传递参数到此控制器方法时,该参数返回为NULL或包含NULL数据。

    [HttpPost]
    public ActionResult UpdateAccessLevels(List<AccessLevel> accessLevels)
    {
        try
        {
            foreach (AccessLevel record in accessLevels)
            {
                unitOfWork.AccessLevelRepository.Update(record);
            }

            unitOfWork.Save();
            return Json("SUCCESS");
        }
        catch (Exception ex)
        {
            return Json(ex.ToString());
        }
    }

以下是通过Fiddler显示的JSON数据,当我传入{ accessLevels:ko.toJSON(viewModel.AccessLevels)}时,它被发送到我的MVC控制器操作中,但控制器参数为空。

[{"Access":[],"Id":1,"AccessLevelDesc":"TEST222"},{"Access":[],"Id":2,"AccessLevelDesc":"TEST222"}]

以下是通过 Fiddler 显示的 JS 数据,当我传递 {accessLevels:ko.toJS(viewModel.AccessLevels)} 时,它将被发送到我的 MVC 控制器操作中。在此示例中,列表有两个成员,但属性中的所有数据都为空。

accessLevels[0][Id] 1
accessLevels[0][AccessLevelDesc]    TEST222
accessLevels[1][Id] 2
accessLevels[1][AccessLevelDesc]    TEST222
如果我将单个对象传递给控制器,它可以正常工作,但是我似乎无法弄清楚如何正确地将ObservableArray中的对象数组从控制器重新提交到POCO实体。

1
被发布的JSON的形状是什么?您可以使用调试器获取此信息,或使用Fiddler进行捕获,然后更新您的帖子以包含此信息。谢谢! - Brian Ball
已按要求编辑了我的问题并提供了相关信息。 - ccorrin
我不知道ASP.net如何处理映射,但您正在将一个字符串传递给您的post(ko.toJSON()返回一个字符串)。那不应该是一个数组吗?你不应该使用ko.toJS()吗? - Jeff Mercado
你尝试过使用 IEnumerable<AccessLevel> accessLevels 吗? - Kyeotic
如果我使用ko.toKS,MVC操作的参数中会传递正确数量的项目,但由于某种原因它们的成员都是null。 - ccorrin
IEnumerable<AccessLevel> 给我带来的结果与使用 List<T> 或数组相同。 - ccorrin
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
13

尝试以JSON请求发送它,通过指定正确的请求Content-Type头部:

updateAccessLevels = function () {
    $.ajax({
        url: '/DataService/UpdateAccessLevels', 
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: ko.toJSON(viewModel.AccessLevels),
        success: function(status) {
            alert(status);
        }
    });
};

这个完美地运行了。谢谢你。那么,试图理解这个,为什么没有手动指定内容类型就会变成 null? - ccorrin
因为您发送JSON字符串并未指定内容类型,所以默认的模型绑定程序严格来说不知道如何进行绑定。您可以传递 { accessLevels: viewModel.AccessLevels },而无需调用任何 ko.toJSON,但这仅适用于数组内的原始类型。对于更复杂的类型,最好使用JSON请求。 - Darin Dimitrov
这很有道理,因为当我发送一个项目而不是一个数组时,它可以正常工作。谢谢你,Darin。 - ccorrin
这个问题每次都会让我措手不及,我总是忘记包括 contentType: 'application/json; charset=utf-8' - ViqMontana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,