拥有这些ASP.NET MVC视图模型:
public class User
{
public string Name { get; set; }
public LabeledEmail LabeledEmail { get; set; }
}
public class LabeledEmail
{
public IList<ContactLabel> Labels;
public IList<ContactEmail> Emails;
}
和Knockout视图模型如下:
<script type="text/javascript">
$(function() {
ko.applyBindings(viewModel);
$("#profileEditorForm").validate({
submitHandler: function(form) {
if (viewModel.save())
window.location.href = "/";
return false;
}
});
});
var viewModel = {
Name: ko.observable("@Model.Name"),
EmailLabels: ko.observableArray(@Html.Json(Model.LabeledEmail.Labels.Select(l => l.Name)) || []),
Emails: ko.observableArray(@Html.Json(Model.LabeledEmail.Emails) || []),
addEmail: function() {
viewModel.Emails.push(@Html.Json(new ContactEmail()));
},
removeEmail: function(eml) {
viewModel.Emails.remove(eml);
},
saveFailed: ko.observable(false),
// Returns true if successful
save: function() {
var saveSuccess = false;
viewModel.saveFailed(false);
jQuery.ajax({
type: "POST",
url: "@Url.Action("MyAction", "MyController")",
data: ko.toJSON(viewModel),
dataType: "json",
contentType: "application/json",
success: function(returnedData) {
saveSuccess = returnedData.Success || false;
viewModel.saveFailed(!saveSuccess);
},
async: false
});
return saveSuccess;
}
};
</script>
回复到控制器的帖子是User.Name
,但User.LabeledEmail
为空。
我必须按照我的方式压扁模型,以便能够在其他地方单独使用列表。
我知道viewModel.Emails在保存时已正确填充,但User.LabeledEmails以某种方式返回null。
它基本上归结为分配Model.LabeledEmail.Emails
viewModel.Emails
并且交易将会解决,但似乎我不知道如何找到任何合适的例子。
提前谢谢。
答案 0 :(得分:3)
您的JSON数据结构应该与C#类的结构匹配,尤其是属性名称。所以你需要发送一个看起来像这样的JSON:
{
Name: 'somename',
LabeledEmail: {
Labels: [ somelements ],
Emails: [ someelements ]
}
}
所以改变你的data: ko.toJSON(viewModel),
:
data: JSON.stringify({
Name: viewModel.Name(),
LabeledEmail: {
Labels: viewModel.EmailLabels(),
Emails: viewModel.Emails()
}
})
或者只是在客户端和服务器上使用相同结构的数据......
作为旁注:您的C#视图模型需要具有属性而不是字段才能使MVC模型绑定器正常工作:
public class User
{
public string Name { get; set; }
public LabeledEmail LabeledEmail { get; set; }
}
public class LabeledEmail
{
public IList<ContactLabel> Labels { get; set; }
public IList<ContactEmail> Emails { get; set; }
}