Knockout viewmodel传递给行动空洞

时间:2017-07-06 13:19:09

标签: json post knockout.js action asp.net-mvc-ajax

我有一个控制器动作,我试图从淘汰赛发布模型:

    [HttpPost]
    public void AddItems(MyViewModel model)
    {
        [...]
    }

淘汰赛:

self.AddItems = function (data, event) {
    var url = "/MyController/AddItems";
    var target = event.target || event.srcElement;
    var model = ko.toJSON(self);
    $.post(url,
            model,
            function (result) {

            })
        .success(function () { console.log("AddItems second success"); })
        .error(function () { console.log("AddItems error"); })
        .complete(function () { console.log("AddItems complete"); });

    // this doesn't work either
    //var model2 = ko.toJSON({ model: self });
    //$.ajax(url, {
    //    data: model,
    //    type: "post",
    //    async: false,
    //    contentType: "application/json",
    //    success: function (data) {
    //        console.log("AddItems second success");
    //    },
    //    error: function (xmlHttpRequest, textStatus, errorThrown) {
    //        console.log("AddItems error");
    //    }
    //});
}

我已经注释了另一个我尝试过的帖子 - 这个没有达到控制器操作,总共在js控制台中返回500错误。

模特:

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

    public string Ref { get; set; }

    public List<ItemViewModel> Items { get; set; }

    public decimal PriceTotal { get; set; }
}

发布到操作的模型具有正确的结构,但所有属性都为空或为空。

如何使用正确的对象数据将knockout viewmodel传递给动作?

***** 编辑 *****

我认为这个动作并没有得到json模型。

因为当我传递一个手写的原始对象模型时:

var model4 = {
  "Ref": "sgsgsasg",
  "Id": 1,
  "PriceTotal": 382
}

它可以很好地使用正确的值进行操作。

当淘汰赛通过json然后动作无法将其转换为mvc模型。

2 个答案:

答案 0 :(得分:1)

我很确定您只缺少内容类型标头。

默认情况下,jQuery将数据发布为application/x-www-form-urlencoded。你想要application/json。 jQuery $.ajax()允许您配置内容类型:

self.AddItems = function () {
    return $.ajax({
        url: "/MyController/AddItems",
        data: ko.toJSON(self),
        contentType: "application/json"
    })
    .done(function () { console.log("AddItems success"); })
    .fail(function () { console.log("AddItems error"); })
    .always(function () { console.log("AddItems complete"); });
}

附注:从函数返回请求使您可以在其他地方附加更多行为:

self.something = function () {
    // do some work on the viewmodel
    self.AddItems().done(function () {
        // we are done
    });
}

答案 1 :(得分:0)

您尚未传递您的网址所期望的参数,因此为500。

self.AddItems = function (data, event) {
    var url = "/MyController/AddItems";
    var target = event.target || event.srcElement;
    $.ajax(url , {
       type: "POST",
       cache: false,
       data: { model: ko.toJSON(self) }
    }).done(function () {
       console.log("AddItems second success");
    }).fail(function (jqXHR, textStatus, errorThrown) {
       console.log("AddItems complete");
    });
}

控制器

[HttpPost]
public void AddItems(string model)
{
    var audit = InsertAudit();
    try
    {
        MyViewModel data = JsonConvert.DeserializeObject<MyViewModel>(model);
        //Logic here
    }
    catch (Exception ex)
    {
         FailAudit(audit.ID, ex.ToString());
    }
}