传递给操作的 Knockout 视图模型为空

Knockout viewmodel passed to action coming empty

提问人:nickornotto 提问时间:7/6/2017 最后编辑:nickornotto 更新时间:7/6/2017 访问量:245

问:

我有一个控制器操作,我正在尝试从 knockout 发布模型:

    [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; }
}

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

如何将淘汰赛视图模型传递给具有正确对象数据的动作?

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

我认为该操作没有获得json模型。

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

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

它很好地采取了行动,并具有正确的值。

当 knockout 传递 json 时,操作无法将其转换为 mvc 模型。

JSON 发布 淘汰.js 操作 ASP.NET-MVC-AJAX

评论

0赞 nickornotto 7/6/2017
我使用这个示例 c-sharpcorner.com/UploadFile/5ff76e/...从json反序列化模型,并用于将其传递到操作中{ model: ko.toJSON(self) }

答:

0赞 tyler_mitchell 7/6/2017 #1

您尚未传递 url 期望的参数,因此为 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());
    }
}

评论

0赞 tyler_mitchell 7/6/2017
它没有正确反序列化,请参阅编辑,我实际上更喜欢这种方式,因为您可以在反序列化之前审核数据,因此如果它失败,您可以捕获异常并记录它,这样就不会丢失数据。
0赞 nickornotto 7/6/2017
这命中了操作,但模型对象为 null
1赞 Tomalak 7/6/2017 #2

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

默认情况下,jQuery 将数据作为 .你想要。jQuery 允许您配置内容类型:application/x-www-form-urlencodedapplication/json$.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
    });
}

评论

0赞 nickornotto 7/6/2017
这会返回 500 错误,调试器无法执行操作,问题出在内容类型以外的其他地方
0赞 Tomalak 7/6/2017
好吧,服务器必须提供一些错误的详细信息。你检查过回复吗?