加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-4 – 将复杂的viewmodel发布到控制器

发布时间:2020-12-16 07:05:20 所属栏目:asp.Net 来源:网络整理
导读:我试图掌握Knockout(2.2.0)背后的概念. 由于我正在使用ASP.NET MVC 4,我想我可以遵循一个具有“复杂”视图模型(master-details)的示例. 我唯一能找到的就是MvcMusicStore. 代码很容易阅读,我已经想出如何从服务器读取视图模型并在客户端上构建视图模型. 这是
我试图掌握Knockout(2.2.0)背后的概念.
由于我正在使用ASP.NET MVC 4,我想我可以遵循一个具有“复杂”视图模型(master-details)的示例.

我唯一能找到的就是MvcMusicStore.

代码很容易阅读,我已经想出如何从服务器读取视图模型并在客户端上构建视图模型.

这是我的C#ViewModel:

public class Person
{
    public Person()
    {
        this.Phones = new List<Phone>();
    }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }

    public IList<Phone> Phones { get; set; }
}

public class Phone
{
    public string Model { get; set; }
    public string Number { get; set; }
}

我的控制器将一个填充的模型返回给视图,该视图将其转换为一个挖空视图模型:

var data = @Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));
var model = ko.mapping.fromJS(data);
ko.applyBindings(model);

我使用了Rob Conery使用的相同模式,上面的代码是简化版本.

这是我的看法:

@using (@Html.BeginForm("Index","Home",FormMethod.Post))
{
    <input id="Name" name="Name" type="text" data-bind="value: Name" value="" />
    <br />
    <input id="Surname" name="Surname" type="text" data-bind="value: Surname" value="" />
    <br />
    <table>
    <tbody data-bind="foreach: Phones">
        <tr>
            <td><input type="text" data-bind='value: Model' /></td>
            <td><input type="text" data-bind='value: Number' /></td>
        </tr>
    </tbody>
    </table>
    <input type="submit" value="Send" />  
}

现在,我想提交我的FORM并在我的控制器上阅读更新的视图模型.

为了达到这个目的,我使用了与MvcMusicStore相同的解决方案.
如果你看line 49 Rob试图序列化FORM:

var data = $("#orderForm").serialize();

并POST到控制器:

$.post("/orders/edit",data,callback);

我似乎无法使这个代码与我的视图模型一起工作.
我的控制器:

[HttpPost]
public JsonResult Index(Models.Person viewModel)
{
...
}

似乎无法反序列化子进程,如果调试客户端,我可以看到seralize方法也无法序列化它们.

实际上,我不明白为什么他会尝试序列化FORM.因为我们有一个由淘汰赛管理的视图模型.
有没有其他方法我可以序列化像这样的“复杂”模型并将其发布到控制器?

你认为这个解决方案(MvcMusicStore)是正确的做事还是我应该遵循其他模式?

任何帮助,将不胜感激.

UPDATE

我想我找到了一个解决方案但我必须做更多的测试.
如果我使用toJSON KO方法:

var data = ko.toJSON(model);

我可以将整个viewmodel序列化正确;然后我必须使用$.ajax POST数据

$.ajax({
    type: 'POST',dataType: 'json',contentType: 'application/json; charset=utf-8',url: "/Home/Index",data: dataToSave,success: callback,error: function (req,status,error) {
       alert("Status: " + status + " Error: " + error);
      }
});

这样一切似乎都运行正常,但是,我仍然想知道是否有任何推荐的方法.

Michael Berkompas和nemesv给了我有用的信息,我已经整理了一个简单的application,以防其他人感兴趣.

解决方法

问题是表格内部的输入元素没有名称属性.

您可以使用attr binding设置名称,因为MVC在model binding collection时需要特殊的名称格式,您需要编写:

<tbody data-bind="foreach: Phones">
        <tr>
            <td><input type="text" data-bind="value: Model,attr: { name: 'Phones[' + $Index() + '].Model' }" /></td>
            <td><input type="text" data-bind="value: Number,attr: { name: 'Phones[' + $Index() + '].Number' }" /></td>
        </tr>
</tbody>

或者因为你无论如何都拥有你的viewmodel,你可以直接将它发送给你的控制器:

var model = ko.mapping.fromJS(data);

//...

$.ajax({
    type: 'POST',url: "/orders/edit",contentType: "application/json",data: ko.mapping.toJSON(model),success: callback
});

请注意,在这种情况下,您不能使用$.post,因为您需要指定contentTypeas“application / json”.

但我认为没有推荐的方法来做到这一点. $(“#orderForm”).serialize()(具有我提到的正确输入名称)和ko.toJSON(模型)都可以工作,因为区别仅在于如何为ajax请求准备/编码数据.

我认为这更像是个人偏好使用者.在这种特殊情况下,执行ko.toJSON(模型)方式似乎更好,因为您不必处理ASP.NET MVC的特殊输入名称的生成.您可以将viewmodel原样发送到服务器.使用淘汰赛时感觉更自然.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读