C# MVC4复杂类型模型在post后为空
这是我的模型C# MVC4复杂类型模型在post后为空,c#,asp.net-mvc,asp.net-mvc-4,razor,C#,Asp.net Mvc,Asp.net Mvc 4,Razor,这是我的模型 public class AdministrationModel { public string FirstName { get; set; } public string LastName { get; set; } public string EmailAddress { get; set; } public bool IsApproved { get; set; } } 这是我的控制器 public ActionResult GetTabContent(st
public class AdministrationModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public bool IsApproved { get; set; }
}
这是我的控制器
public ActionResult GetTabContent(string id)
{
switch (id)
{
case "tab3":
model = GetAllUsersInfo();
viewName = "Administration";
break;
}
return View(viewName);
}
private List<AdministrationModel> GetAllUsersInfo()
{
List<AdministrationModel> userList = new List<AdministrationModel>();
foreach (MembershipUser user in Membership.GetAllUsers())
{
UserProfile userProfile = UserProfile.GetUserProfile(user.UserName);
userList.Add(new AdministrationModel { EmailAddress = user.Email, IsApproved = user.IsApproved, FirstName = userProfile.FirstName, LastName = userProfile.LastName });
}
return userList;
}
[HttpPost]
public ActionResult Administration(List<AdministrationModel> model)
{
return View();
}
public ActionResult GetTabContent(字符串id)
{
开关(id)
{
案例“表3”:
模型=GetAllUsersInfo();
viewName=“管理”;
打破
}
返回视图(viewName);
}
私有列表GetAllUsersInfo()
{
List userList=新列表();
foreach(Membership.GetAllUsers()中的MembershipUser用户)
{
UserProfile UserProfile=UserProfile.GetUserProfile(user.UserName);
userList.Add(新的管理模型{EmailAddress=user.Email,IsApproved=user.IsApproved,FirstName=userProfile.FirstName,LastName=userProfile.LastName});
}
返回用户列表;
}
这是我的看法
@model List<AdminContainerModel>
@using (Html.BeginForm("Administration", "Account"))
{
<fieldset>
<div>
@foreach (AdministrationModel AM in Model)
{
<div>
<div class="colFull">@Html.DisplayFor(modelItem => AM.FirstName)</div>
<div class="colFull">@Html.DisplayFor(modelItem => AM.LastName)</div>
<div class="colFull">@Html.DisplayFor(modelItem => AM.EmailAddress)</div>
<div class="colPartial"><input type="checkbox" checked="@AM.IsApproved"/> </div>
<div class="clear"></div>
</div>
}
</div>
<input type="submit" value="Update Account" />
</fieldset>
}
@型号列表
@使用(Html.BeginForm(“管理”、“帐户”))
{
@foreach(模型中的管理模型AM)
{
@DisplayFor(modelItem=>AM.FirstName)
@DisplayFor(modelItem=>AM.LastName)
@DisplayFor(modelItem=>AM.EmailAddress)
}
}
当用户单击更新帐户按钮时,它将转到控制器
public ActionResult GetTabContent(string id)
{
switch (id)
{
case "tab3":
model = GetAllUsersInfo();
viewName = "Administration";
break;
}
return View(viewName);
}
private List<AdministrationModel> GetAllUsersInfo()
{
List<AdministrationModel> userList = new List<AdministrationModel>();
foreach (MembershipUser user in Membership.GetAllUsers())
{
UserProfile userProfile = UserProfile.GetUserProfile(user.UserName);
userList.Add(new AdministrationModel { EmailAddress = user.Email, IsApproved = user.IsApproved, FirstName = userProfile.FirstName, LastName = userProfile.LastName });
}
return userList;
}
[HttpPost]
public ActionResult Administration(List<AdministrationModel> model)
{
return View();
}
[HttpPost]
公共行动结果管理(列表模型)
{
返回视图();
}
在这个方法中,模型总是空的。然而,呈现一切的视图是完美的,并且显示了我希望它显示的内容。我做错了什么?您的
@model
指令不正确,它应该是完全限定的类型名
在这种情况下:
@model TheNamespace.AdministrationModel
更新后的问题 尝试使用:
@Html.EditorFor(Model)
这将为您的列表调用专门的编辑器模板
使用集合时,为了正确处理它们,使它们在post上绑定到模型,而不需要任何额外的分支工作,您需要确保它们的索引正确,您可以使用for循环来完成此操作,例如:
@for (int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(m => m[i].FirstName)
@Html.HiddenFor(m => m[i].LastName)
@Html.HiddenFor(m => m[i].EmailAddress)
<div>
<div class="colFull">@Html.DisplayFor(m => m[i].FirstName)</div>
<div class="colFull">@Html.DisplayFor(m => m[i].LastName)</div>
<div class="colFull">@Html.DisplayFor(m => m[i].EmailAddress)</div>
<div class="colPartial">@Html.CheckBoxFor(m => m[i].IsApproved)</div>
<div class="clear"></div>
</div>
}
替换为:
@Html.HiddenFor(m => m[i].ClientId)
这样,您就不会发回名字、姓氏或电子邮件地址,而只是对实际客户的一个引用,即勾选、取消勾选
要回答评论中关于跟踪原始值的另一个问题,在控制器方法中,您只需从数据库中获取原始值,然后以下是如何检测哪些值不同,如:
[HttpPost]
public ActionResult Administration(List<AdministrationModel> model)
{
var originalMatches = GetAllUsersInfo();
var differences = (from o in originalMatches
join c in model on o.ClientId equals c.ClientId
where c.IsApproved != o.IsApproved).ToList()
return View();
}
[HttpPost]
公共行动结果管理(列表模型)
{
var originalMatches=GetAllUsersInfo();
var差异=(从原始匹配中的o开始)
在o.ClientId等于c.ClientId的模型中加入c
其中c.IsApproved!=o.IsApproved
返回视图();
}
如果您想在提交时返回带有模型的列表项,则需要使用for循环,而不是foreachMatty的答案将起作用
如果您想避免必须指定索引(如果您有ICollection,那么这将不起作用),您可以定义一个子模板,正如Xander所解释的那样
好处是,您仍然可以在AdminContainerModel视图中获得所有强类型的intellisense,并且MVC会将这些项目挂回到您的列表中,以便您即时返回
下面是一个例子:
主编辑器模板(正如Xander所说):
@model IEnumerable
@使用(Html.BeginForm(“管理”、“帐户”))
{
@Html.EditorForModel()
你说的是视图吗?如果是的话,我只是删除了名称空间,将其发布到这里。显示视图显示数据没有问题,它在HTTPPost调用期间模型为null。你想让我用EditorFor替换DisplayFor吗?我试过了,发布后我的模型仍然为null。我确信我遗漏了什么(只是不确定它是什么)您需要一个EditorTemplate视图来映射AdministrationModel
Html.EditorFor(Model)
将查找此视图。使用此视图后,无需在列表中循环。好的,我是这样做的。但是,这会将模型中的所有内容呈现为可编辑字段。我只想编辑“IsApproved”复选框。选中/取消选中后,我需要根据电子邮件地址查找用户并更新他/她。我希望这是有意义的。您可以在viewmodel的属性上设置表示自己为“不可编辑”的属性-这应该有帮助:这对我没有帮助。在回发事件中-名字、姓氏和电子邮件地址的所有值都为空。我想要一个所有已更改值的集合(复选框从选中变为未选中或未选中变为选中)抱歉,请检查我的编辑,我忘记了displayFors没有将名称属性放在字段上以正确地进行模型绑定(我们更改了模板进行绑定)。在控制器中,您可以在未签入的链接上进行筛选,例如var clients=model.Where(c=>c.IsApproved)。ToList()它工作得很好,但是我有两个问题:1.如果有人更改隐藏字段值(几乎每个浏览器中都有开发工具)然后模型中的值也会发生变化2.lamda表达式只给出所有已检查的列表,我如何跟踪已检查和已在此会话中检查的。1.这是一个面向公众的网站,您不想让人们操纵它吗?2.您可以将您的模型设为复杂类型控制正在创建两个客户端列表,一个是您正在编辑的客户端,另一个是原始客户端。对两个集合重复上述for循环,但只有原始集合的所有隐藏字段。只是想说声谢谢!将foreach替换为修复了绑定。如果他所更改的是foreach,那么这应该是一个注释,因为它可以工作,所以这是一个解决方案好的,问题是你只是在“指出一些东西”——答案应该比这更深刻对不起,我想我是想礼貌一点,在写之前识别出被接受的答案
@model AdminContainerModel
<div>
<div class="colFull">@Html.DisplayFor(modelItem => AM.FirstName)</div>
<div class="colFull">@Html.DisplayFor(modelItem => AM.LastName)</div>
<div class="colFull">@Html.DisplayFor(modelItem => AM.EmailAddress)</div>
<div class="colPartial"><input type="checkbox" checked="@AM.IsApproved"/>
</div>
<div class="clear"></div>