【问题标题】:Passing knockout.js observablearray object to MVC Controller Action?将 knockout.js observablearray 对象传递给 MVC 控制器操作?
【发布时间】:2012-10-02 12:55:22
【问题描述】:

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

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

下面是通过提琴手显示的 JSON 数据,当我传入 { accessLevels: ko.toJSON(viewModel.AccessLevels) } 时,控制器参数将使用此参数为空

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

下面是通过提琴手显示的 JS 数据,当我传入 { accessLevels: ko.toJS(viewModel.AccessLevels) } 时,这些数据被发布到我的 MVC 控制器操作中,在这种情况下,列表有两个预期的成员,但属性中的数据全部为空

accessLevels[0][Id] 1
accessLevels[0][AccessLevelDesc]    TEST222
accessLevels[1][Id] 2
accessLevels[1][AccessLevelDesc]    TEST222

如果我将单个对象传递给我的控制器,它工作得很好,但我似乎无法找出将对象数组从 obervablearray 发布回 POCO 实体的正确方法。

【问题讨论】:

  • 发布的 JSON 格式是什么?使用调试器获取此信息或使用Fiddler 捕获它,然后使用此信息更新您的帖子。谢谢!
  • 使用请求的信息编辑了我上面的问题。
  • 我不知道 ASP.net 是如何处理映射的,但是您正在将一个字符串传递给您的帖子(ko.toJSON() 返回一个字符串)。那不应该是一个数组吗?你不应该使用ko.toJS()吗?
  • 你试过IEnumerable&lt;AccessLevel&gt; accessLevels吗?
  • 如果我使用 ko.toKS,MVC 操作的参数中会出现正确数量的项目,但是由于某种原因,它们的成员都为空。

标签: javascript jquery asp.net-mvc knockout.js


【解决方案1】:

尝试通过指定正确的请求 Content-Type 标头将其作为 JSON 请求发送:

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 的形式出现?
  • 因为您发送的是 JSON 字符串并且没有指定内容类型。默认模型绑定器完全不知道如何绑定它。您可以在不调用任何ko.toJSON 的情况下通过{ accessLevels: viewModel.AccessLevels },但这仅适用于数组内的原始类型。对于更复杂的类型,最好使用 JSON 请求。
  • 这是有道理的,因为当我发送一个项目而不是一个数组时它工作正常。谢谢达林。
  • 这每次都让我抓狂,我总是忘记包含contentType: 'application/json; charset=utf-8',
猜你喜欢
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-27
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多