将 KnockoutJS 数据 POST 到 MVC 控制器时无法绑定。

5
我正在尝试发布映射的 KnockoutJS 模型。我可以在调试时看到,JSON 是正确的。但是服务器显示 Product 为0(空)。虽然它包含了1个项目。 MVC 控制器:
[HttpPost]
public ActionResult Test(MyModel model, FormCollection fc)
{
   return RedirectToAction("index");
}

AJAX 提交:

$('#btnSubmit').click(function (event) {
        var theModel = ko.mapping.toJSON(viewModel);
        debugger;
        $.ajax({
            type: 'POST',
            url: "@Url.Action("Test", "Home")",
            data: theModel,
            contentType: 'application/json; charset=utf-8',
            success: function (result) {
                if (!result.success) {
                    //alert(result.error);
                }
                else { }
            }
        });
    });

这是一个部分的 JSON 对象:
"Products":[{"Id":2,"Name":"bread"}]

我做错了什么?

编辑:

public class MyModel
{
   public int User { get; set; }
   public string Address { get; set; }
   public string ZipCode { get; set; }
   public List<Product> Products { get; set; }

}

public class Product
{
   public int Id { get; set; }
   public string Name { get; set; } 
}

你能发布 MyModel 吗? - Joffrey Kern
我们使用 ko.dataFor。http://stackoverflow.com/questions/14968565/does-ko-datafor-work-with-select-elements - Matt Bodily
@JoffreyKern,MyModel已添加。 - Quoter
正如我们所看到的,您的“Product”没有“TypeId”的概念。它具有“Id”的属性。但是,您发布的“JSON”包含一个“TypeId”。 - Shuhel Ahmed
尝试修复代表“产品”的javascript模型。将TypeId替换为Id或反之亦然。 - Shuhel Ahmed
显示剩余2条评论
2个回答

3
这里是一个完整的、经过测试的示例(从控制器发送模型并进行发布): 控制器
public ActionResult Test()
{
    var model = new MyModel();
    model.Products = new List<Product> { new Product { Id = 2, Name = "bread" } };
    return View(model);
}

[HttpPost]
public ActionResult Test(MyModel model, FormCollection fc)
{
    // Count equals one
    var count = model.Products.Count();
    return RedirectToAction("index");
}

模型

public class MyModel
{
    public int User { get; set; }
    public string Address { get; set; }
    public string ZipCode { get; set; }
    public List<Product> Products { get; set; }
}
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}

视图

@model MyModel
<form method="post">
    <input id="btnSubmit" type="submit" value="submit" />
</form>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/knockout-2.2.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script type="text/javascript">

    var Product = function (Id, Name) {
        self = this;
        self.Id = Id;
        self.Name = Name;
    }

    var mapping = {
        'Products': {
            create: function (options) {
                return new Product(options.data.Id, options.data.Name);
            }
        }
    }


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

    var viewModel = new MyModel(@Html.Raw(Json.Encode(Model)));

    $('#btnSubmit').click(function (event) {
        event.preventDefault();
        var theModel = ko.mapping.toJSON(viewModel);
        debugger;
        $.ajax({
            type: 'POST',
            url: "@Url.Action("Test", "Home")",
            data: theModel,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (result) {
                if (!result.success) {
                    //alert(result.error);
                }
                else { }
            }
        });
    });

    </script>

请尝试我的其他建议。我通过遵循这些步骤得到了一个可工作的示例。我知道你的意思,可以使用标准的post back,但你必须知道模型绑定器期望的所有表单设置,并确保knockout将它们保持同步。 - hutchonoid
所有JS对象值必须匹配。对我来说,最后的问题是数据类型,需要使用模型绑定器进行映射。 - hutchonoid
它们都匹配,我没有触碰任何其他对象,只是填充了产品“List<>”。但它仍然无法绑定模型。除了映射部分之外,我做了你说的事情。不知何故,那不起作用。但对于这种情况应该没有关系。 - Quoter
我改变了模型以便更简单。这就是为什么它们不同的原因。但 Id/TypeId 不应该有影响。它们是同步的。除了 AJAX 之外,还有其他的 POST 方法吗?顺便说一下,我已经尝试了强制刷新。每次更改脚本时,我都会经常这样做。 - Quoter
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/42811/discussion-between-hutchonoid-and-quoter - hutchonoid
显示剩余3条评论

0

在使用 Fiddler 进行更多调查后,发现我收到了一个带有以下消息的 500 错误:

System.MissingMethodException: No parameterless constructor defined for this object.

在模型中添加了无参构造函数后,我仍然收到错误消息。这是因为我的模型中有几个SelectList。所以它无法绑定到模型。
SO帖子上找到了解决方案(查找Chris S的答案)。希望当其他人面临此问题时,这可以帮助他们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接