将knockout.js视图模型发布到.Net Core(2.0)MVC控制器

时间:2017-11-09 08:57:43

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

概述

目前,我尝试创建一个ASP.NET Core MVC网站,该网站在页面加载时从服务器获取数据。之后,该页面使用knockout.js维护一个viewmodel来更新从服务器发送的数据(在第一步中)。最后,有一个按钮可以将编辑后的数据发送回服务器(通过AJAX请求)。但是我的服务器方法中的相应值始终为空。

当前方法

首先,有我的模型类。

    public class Order
    {
        public string Name { get; set; }
        public int TemplateId { get; set; }
        public decimal Price { get; set; }

        public int Contingent { get; set; }
        public int MaximumOrder { get; set; }
        public int UserOrderCount { get; set; }

        public Order() { }
        public Order(SnackOffer offer)
        {
            Name = offer.Template.Name;
            TemplateId = offer.Template.SnackTemplateId;
            Price = offer.Price;
        }
    }

在我看来,我使用模型类作为List(List)并加载如下数据:

var model = new viewModel();
    @(Json.Serialize(Model.Offers)).forEach(function (item, index) {
        model.offers.push({
            name: item.name,
            templateId: item.templateId,
            contingent: ko.observable(item.contingent),
            userOrderCount: ko.observable(item.userOrderCount),
            price: item.price,
            maximumOrder: item.maximumOrder
        });
    })

viewModel的定义如下(可读性为shortend):

function viewModel() {
        var self = this;
        self.offers = ko.observableArray();
}

现在有人按下提到的更新按钮后,我调用了这个javascript函数:

self.ConfirmOrder = function () {
            var data = ko.toJSON(self.offers);

            $('#overlay').css('display', 'block');
            $.ajax({
                type: 'post',
                url: '/Snack/ConfirmOrder',
                data: data,
                contentType: 'application/json; charset=utf-8',
                success: function (result) {
                    $('#overlay').css('display', 'none');
                },
                error: function (result) {
                    console.log(result);
                    $('#overlay').css('display', 'none');
                }
            });
        }

在这里你可以看到我使用ko.toJSON方法将observableArray转换为JSON字符串,并使用此字符串作为ajax帖子的数据参数。

MVC控制器中的ConfirmOrder方法目前看起来像这样:

    [HttpPost]
    public void ConfirmOrder(List<OrderSnackViewModel.Order> offers)
    {
        foreach (var item in offers)
        {
            _logger.LogInformation(item.Name);
        }            
    }

没有逻辑,因为创建了商品列表(因此不为空),但列表商品的数量始终为0.

在一个具体的例子中,这是我在加载视图时从服务器收到的JSON字符串:

[{&#34;名称&#34;:&#34;试验&#34;&#34; templateId&#34;:1,&#34;价格&#34;:1.94,&#34;然& #34;:4,&#34; maximumOrder&#34;:7,&#34; userOrderCount&#34;:0},{&#34; name&#34;:&#34; Test 1&#34;,& #34; templateId&#34;:2&#34;价格&#34;:1.50,&#34;然&#34;:30,&#34; maximumOrder&#34;:7,&#34; userOrderCount&#34 ;:0}]

这是我用ajax调用生成的字符串:

[{&#34;名称&#34;:&#34;试验&#34;&#34; templateId&#34;:1,&#34;然&#34:4,&#34; userOrderCount& #34;:0,&#34;价格&#34;:1.94,&#34; maximumOrder&#34;:7},{&#34;名称&#34;:&#34;测试1&#34;,& #34; templateId&#34;:2&#34;然&#34;:30,&#34; userOrderCount&#34;:0,&#34;价格&#34;:1.5,&#34; maximumOrder&#34 ;:7}]

我已尝试过什么:

  • 我试图在我的MVC控制器中使用FromBody
  • 我尝试使用名称商品为JSON输出添加前缀,以便我的控制器方法可以将JSON字符串项映射到对象。 (例如,数据=&#39; {&#34;提供&#34;:&#39; +数据+&#39;}&#39 ;;)
  • 我尝试重命名模型的属性以完全匹配JSON名称。所以我将Name重命名为contingent,Contingent为contingent等等。
  • 我试图在MVC控制器操作中使用数组而不是List

在某处可以帮我解决这个问题吗? (如果您需要更多信息,请不要犹豫)

1 个答案:

答案 0 :(得分:0)

感谢@adiga的输入,我找到了(我的)错误的解决方案。

[HttpPost]
public JsonResult ConfirmOrder([FromBody]List<Order> offers)
{        
    _logger.LogInformation("COUNT -> " + offers.Count());
    foreach (var item in offers)
    {
        _logger.LogInformation(item.Name);
    }            
}

这是可行的解决方案。我以为我已经尝试过了,但也许我已经忘记了ajax帖子的内容类型。

var data = ko.toJSON(self.offers);

$('#overlay').css('display', 'block');

$.ajax({
    type: 'post',
    url: '/Snack/ConfirmOrder',
    data: data,
    contentType: 'application/json; charset=utf-8',
    success: function (result) {
        //location.reload(); 
        $('#overlay').css('display', 'none');
    },
    error: function (result) {
        console.log(result);
        $('#overlay').css('display', 'none');
    }
});

再次感谢所有回复!