来自KnockoutJS的MVC核心中的模型绑定

时间:2017-11-28 20:30:41

标签: knockout.js asp.net-core-mvc

我正在跟随Pluralsight'亲子 - EF,MVC,Knockout'课程,这是为MVC4编写的。我正在攻击MVC Core并且正在猛烈反对我认为POST回到服务器的模型绑定问题。

我的控制器:

        public JsonResult Save(SalesOrderViewModel salesOrderViewModel)
    {
        if (ModelState.IsValid)
        {
            var salesOrder = new SalesOrder();
            salesOrder.CustomerName = salesOrderViewModel.CustomerName;
            salesOrder.PONumber = salesOrderViewModel.PONumber;
            _context.SalesOrder.Add(salesOrder);
            _context.SaveChanges();

            return Json(JsonConvert.SerializeObject(salesOrderViewModel));
        }
        else
        {
            return Json(JsonConvert.SerializeObject(ModelState));
        }
    }

// ModelState进入'有效'但所有值都为空。

我的ajax电话:

 SalesOrderViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, {}, self);

    console.log(self);

    self.save = function () {
        console.log(self);
        console.log(ko.toJSON(self));
        debugger;
        $.ajax({
            url: "/Sales/Save/",
            type: "POST",
            data: ko.toJSON(self),
            headers: {
                "contentType": "application/json"
            },

            success: function (data) {
                if (data.salesOrderViewModel)
                    ko.mapping.fromJS(data.salesOrderViewModel, {}, self);
            },
            always: function (data) {
                console.log(data);
            }
        });
    }
};  
ajax回发上的console.log是:

postback data: {"SalesOrderId":0,"CustomerName":null,"PONumber":null}

检查Chrome在FormData上的报告显示: {"SalesOrderId":0,"CustomerName":"Steve","PONumber":"PO","MessageToClient":null,"__ko_mapping__":{"ignore":[],"include":["_destroy"],"copy":[],"observe":[],"mappedProperties":{"SalesOrderId":true,"CustomerName":true,"PONumber":true,"MessageToClient":true},"copiedProperties":{}}}

pre-post上的console.logs显示出一些奇怪的感觉:'self'与'ko.toJSON(self)'但我不熟悉KO所以不确定它有多奇怪。

enter image description here

我已经看到了一些与模型绑定相关的问题以及我在本地窗口('((Microsoft.AspNetCore.Http.Internal.DefaultHttpRequest)this.Request).Form' threw an exception of type 'System.InvalidOperationException')中看到的错误消息。

更改

contentType: "application/json"

    headers: {
        "ContentType": "application/json"
    },

消除了Locals中的错误,但没有改变行为。控制器的模型仍显示空值。

另一个答案建议在签名中添加'[FromBody]'(也是'[FromForm]) - 既没有帮助我。希望你能!

1 个答案:

答案 0 :(得分:0)

我跟着你自己的路线。而且,和你一样,我注意到Asp.net Core存在一些问题。

我的控制器:

public JsonResult Save([FromBody]SalesOrderViewModel salesOrderViewModel)
        {
            SalesModel salesOrder = new SalesModel();
            salesOrder.CustomerName = salesOrderViewModel.CustomerName;
            salesOrder.PONumber = salesOrderViewModel.PONumber;

            _context.SalesModels.Add(salesOrder);
            _context.SaveChanges();

            salesOrderViewModel.MessageToClient = string.Format("{0}’s sales order has been added to the database.", salesOrder.CustomerName);

            return Json(new { salesOrderViewModel });
        }

我的淘汰赛脚本:

SalesOrderViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, {}, self);

    self.save = function () {
        $.ajax({
            url: "/Sales/Save/",
            type: "POST",
            data: ko.toJSON(self),
            contentType: "application/json",
            success: function (data) {
                if (data.salesOrderViewModel != null) {
                    ko.mapping.fromJS(data.salesOrderViewModel, {}, self);
                }
            }
        });
    }
};

我的创建页面:

@model SolutionName.ViewModels.SalesOrderViewModel
@using Newtonsoft.Json

@{
    ViewBag.Title = "Create a Sales Order";
}

@{
    string data = JsonConvert.SerializeObject(Model);
    }

@section scripts{
    <script src="~/lib/knockout/dist/knockout.js"></script>
    <script src="~/lib/knockout-mapping/build/output/knockout.mapping-latest.js"></script>
    <script src="~/lib/Scripts/SalesOrderViewModel.js"></script>
    <script type="text/javascript">
        var salesOrderViewModel = new SalesOrderViewModel(@Html.Raw(data));
        ko.applyBindings(salesOrderViewModel);
    </script>
}

<h2>@ViewBag.Title</h2>

<p data-bind="text: MessageToClient"></p>

<div>
    <div>
        <label>Customer Name:</label>
        <input data-bind="value: CustomerName" />
    </div>
    <div>
        <label>P.O. Number:</label>
        <input data-bind="value: PONumber" />
    </div>
</div>

<p><button data-bind="click: save">Save</button></p>

<p>
    @Html.ActionLink("Back to List", "Index")
</p>

我用了#34; FromBody&#34;在我的控制器中,保存在数据库中的数据正常工作。但是,不起作用的是按下按钮后保存视图无法正确更新。 我理解使用asp.net Core,这段代码无法正常工作:

ko.mapping.fromJS(data.salesOrderViewModel, {}, self);