【问题标题】:Model binding in MVC core from KnockoutJS来自 KnockoutJS 的 MVC 核心中的模型绑定
【发布时间】:2018-05-12 10:21:18
【问题描述】:

我正在学习为 MVC4 编写的 Pluralsight“使用 EF、MVC、淘汰赛的亲子”课程。我正在针对 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 进入 'Valid' 但所有值均为空。

我的 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' vs. 'ko.toJSON(self)' 但我不熟悉 KO,所以不确定它有多奇怪。

我看到了几个与模型绑定相关的问题以及我在本地窗口('((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]”)——两者都没有帮助我。希望你能!

【问题讨论】:

  • 你能在 ajax 回调中控制日志数据吗?我们也可以从控制器中看到代码吗?
  • 你试过了吗:public JsonResult Save([FromBody]SalesOrderViewModel salesOrderViewModel)
  • 另外,如果您发布了您的 SalesOrderViewModel 代码,您可以将其与表单数据值进行比较,以确保所有变量名称都与绑定匹配。
  • 我也会在你的 JsonResult 上方添加这个保存:[HttpPost("[action]")]
  • 我很确定我在删除 ("[action]") 之前尝试了所有可能的组合,并且只使用了有效的 [HttpPost]。

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


【解决方案1】:

我认为您在使用 ko.toJSON(self) 时向控制器操作发送了错误的数据。这是将整个 ko 模型转换为 Json。而是尝试使用 ko.mapping.toJSON(self) 仅发送映射值

试试:

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.mapping.toJSON(self),
        headers: {
            "contentType": "application/json"
        },

        success: function (data) {
            if (data.salesOrderViewModel)
                ko.mapping.fromJS(data.salesOrderViewModel, {}, self);
        },
        always: function (data) {
            console.log(data);
        }
    });
}
};  

或者你可以只发送这个数据,它被传递到函数中,假设它只包含你想要发布的值。数据:数据

【讨论】:

  • 非常感谢 - 尽管将控制器更改为:[HttpPost] public JsonResult Save([FromBody]SalesOrderViewModel salesOrderViewModel) 我发现任一数据:ko。 mapping.toJSON(self) 或 data: ko.toJSON(self) 的工作方式相同。在andrewlock.net/model-binding-json-posts-in-asp-net-core 对问题进行彻底处理
【解决方案2】:

我正在按照你自己的方式行事。而且,和你一样,我注意到 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>

我在控制器中使用了“FromBody”,并且保存在数据库中的数据可以正常工作。但是,不起作用的是,在按下按钮保存后,视图没有正确更新。 我了解使用 asp.net Core,这段代码无法正常工作:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2014-12-16
    • 2017-09-30
    相关资源
    最近更新 更多