Asp.net mvc 淘汰视图模型部分发回ASP.NET MVC-如何发回完整对象?
具有以下ASP.NET MVC视图模型:Asp.net mvc 淘汰视图模型部分发回ASP.NET MVC-如何发回完整对象?,asp.net-mvc,knockout.js,viewmodel,knockout-2.0,asp.net-mvc-viewmodel,Asp.net Mvc,Knockout.js,Viewmodel,Knockout 2.0,Asp.net Mvc Viewmodel,具有以下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> Ema
public class User
{
public string Name { get; set; }
public LabeledEmail LabeledEmail { get; set; }
}
public class LabeledEmail
{
public IList<ContactLabel> Labels;
public IList<ContactEmail> Emails;
}
公共类用户
{
公共字符串名称{get;set;}
公共LabeledEmail LabeledEmail{get;set;}
}
公共类标签纸
{
公共IList标签;
公共电子邮件;
}
以及如下所示的淘汰视图模型:
<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>
{
Name: 'somename',
LabeledEmail: {
Labels: [ somelements ],
Emails: [ someelements ]
}
}
$(函数(){
应用绑定(视图模型);
$(“#profileEditorForm”).validate({
submitHandler:函数(表单){
if(viewModel.save())
window.location.href=“/”;
返回false;
}
});
});
var viewModel={
名称:ko.observable(@Model.Name”),
EmailLabels:ko.ObservalArray(@Html.Json(Model.LabeledEmail.Labels.Select(l=>l.Name))| |[]),
电子邮件:ko.observearray(@Html.Json(Model.LabeledEmail.Emails)| |[]),
addEmail:function(){
viewModel.Emails.push(@Html.Json(newcontactemail()));
},
removeEmail:函数(eml){
viewModel.Emails.remove(eml);
},
saveFailed:ko.可观察(假),
//如果成功,则返回true
保存:函数(){
var saveSuccess=false;
viewModel.saveFailed(false);
jQuery.ajax({
类型:“POST”,
url:“@url.Action(“MyAction”、“MyController”)”,
数据:ko.toJSON(viewModel),
数据类型:“json”,
contentType:“应用程序/json”,
成功:函数(返回数据){
saveSuccess=returnedData.Success | | false;
viewModel.saveFailed(!saveSuccess);
},
异步:false
});
回报成功;
}
};
正确发回控制器的是User.Name
,但User.LabeledEmail
为空。
为了能够在其他地方单独使用列表,我必须按我的方式展平模型。
我知道viewModel.Emails在保存时是正确填充的,但User.LabeledEmails以某种方式返回null
基本上可以归结为分配Model.LabeledEmail.Emails
查看模型.Emails和交易将被解决,似乎,但我不知道如何,也找不到任何合适的例子
提前谢谢。您的JSON数据结构应该与C#类的结构相匹配,尤其是属性名。因此,您需要发送一个类似以下内容的JSON:
<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>
{
Name: 'somename',
LabeledEmail: {
Labels: [ somelements ],
Emails: [ someelements ]
}
}
因此,更改您的数据:ko.toJSON(viewModel),
:
或者在客户端和服务器上使用相同结构的数据
附带说明:为了使MVC模型绑定器正常工作,您的C#viewmodels需要具有属性而不是字段:
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; }
}
公共类用户
{
公共字符串名称{get;set;}
公共LabeledEmail LabeledEmail{get;set;}
}
公共类标签纸
{
公共IList标签{get;set;}
公共IList电子邮件{get;set;}
}
谢谢。我尝试了这种方法(使用不同的KO视图模型)。如果我这样做,我就不能在我的视图中呈现标签和电子邮件(在我的另一个问题中回答)。我正在构建类似于gmail新联系人的smth——你有[work | home |等]标签和[email | phone | address |等]——不能用敲除法将它们以这种方式放在可变长度列表中。我想我需要以某种方式将表单中填写的内容“组合”到视图模型中。按照您的建议查看模型更改将扼杀目前构建的功能。希望你能理解我的思想流派。谢谢,我不明白你的意思。如果您构建数据:
,正如我所展示的,您不需要在服务器端或客户端更改任何类结构,它应该可以工作(如果您在C端使用属性)….1。将C改为属性(非常好的观察!谢谢)2。我应该把ko.Email和ko.EmailLabels留在ko的根级别,对吗?3.只需要返回您显示的方式,而不是我的toJSON(vm)东西,对吗?我跟得准吗?(因为到目前为止,它甚至会破坏视图,甚至无法正确渲染,即使我确实发送了您描述的Json)。这一切都是有道理的,但不幸的是不起作用。我想我需要花一些时间来弄清楚一些细节,比如为什么……关键是你可以拥有你的C#,因为它适合你的服务器端,你的KO视图模型适合你的UI和绑定。但是,当您想要将数据发送回服务器时,需要在这两个表单之间进行转换。因此,您的jQuery.ajax
数据应该与C#viewmodels的结构相匹配……这在将视图模型传递回控制器时起了作用(在我计算出细节之后)。所以你得到了正确的答案v分+“答案很有用”投票-非常感谢!然而,Q-n-ModelState.IsValid变为false
,没有关于原因的线索。是因为我手工编译回发对象吗?再次感谢