IEnumerable<Model> returning null
本文关键字:returning null gt Model IEnumerable lt | 更新日期: 2023-09-27 18:36:35
我很难通过IEnumerable
作为模型。数据在一个页面上填充表单 - 并且正确填写。提交后,模型返回为 null。
我已经看到了关于此的各种帖子,它们主要引用命名约定,因此我尝试了不同的参数命名方法,以避免模型绑定中的任何混淆。
我还尝试了各种模型和帮助程序来尝试传递数据,并且都有相同的结果。
当前实现:
模型:
public class UserProfileListModel
{
public IEnumerable<UserProfileViewModel> UserProfileViewModels { get; set; }
}
public class UserProfileViewModel
{
public UserProfile UserProfile { get; set; }
public Role UserRole { get; set; }
public Team UserTeam { get; set; }
public Scope UserScope { get; set; }
}
视图:
@model Project.WebUI.Models.UserPRofileListModel
剪 断
<fieldset>
<legend>Administrate Users:</legend>
<table class="adminTbl">
<thead>
<tr>
<th>UserName:</th>
<th>Role:</th>
<th>Team:</th>
<th>Scope:</th>
<th>Update:</th>
<th>Delete:</th>
</tr>
</thead>
<tbody>
@{foreach (var user in Model.UserProfileViewModels)
{
<tr>
<td>
<p>@user.UserProfile.UserName
@{if (!user.UserProfile.Membership.IsConfirmed)
{
using (Html.BeginForm("Confirm", "Account", FormMethod.Post, null)){
@Html.AntiForgeryToken()
@Html.Hidden("Token", user.UserProfile.Membership.ConfirmationToken)
@Html.Hidden("Name", user.UserProfile.UserName)
}
<input type="submit" value="Confirm" />}
}
</p>
</td>
@{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(u => user.UserProfile)
if (user.UserProfile.UserName != User.Identity.Name && user.UserProfile.Membership.IsConfirmed)
{
<td>
@Html.DropDownListFor(u => user.UserRole, Project.WebUI.Controllers.AccountController.RoleList, new { @class = "formdrop" })
</td>
<td>
@Html.DropDownListFor(u => user.UserTeam, Project.WebUI.Controllers.AccountController.TeamList, new { @class = "formdrop" })
</td>
<td>
@Html.DropDownListFor(u => user.UserScope, Project.WebUI.Controllers.AccountController.ScopeList, new { @class = "formdrop" })
</td>
<td>
<input type="submit" value="Save Changes" onclick="return confirm('Are you sure you wish to update this user? ')" />
</td>
}
else
{
/*If user is self or not yet confirmed these are here to buffer the delete button into the last cell*/
<td></td>
<td></td>
<td></td>
<td></td>
}
}
}
<td>
@Html.ActionLink("Delete", "Delete", new { user.UserProfile.UserId }, new
{
onclick = "return confirm('Warning: Action cannot be undone. Are you sure you wish to permanently delete this entry?')"
})
</td>
</tr>
}
}
</tbody>
</table>
</fieldset>
控制器:
填充视图:
public ActionResult AdministrateUsers()
{
populateLists();
var query = repository.UserProfiles.OrderBy(e => e.UserName);
List<UserProfileViewModel> list = new List<UserProfileViewModel>();
foreach(UserProfile up in query)
{
UserProfileViewModel vm = new UserProfileViewModel() { UserProfile = up };
list.Add(vm);
}
UserProfileListModel models = new UserProfileListModel()
{
UserProfileViewModels = list.OrderBy(up => up.UserProfile.UserName)
};
return View(models);
}
接受帖子:
public ActionResult SaveUserChanges(UserProfileListModel model)
{
foreach (UserProfileViewModel upvm in model.UserProfileViewModels)
{
UserProfile up = new UserProfile()
{
UserId = upvm.UserProfile.UserId,
UserEmail = upvm.UserProfile.UserName,
UserName = upvm.UserProfile.UserName
};
if (ModelState.IsValid)
{
repository.SaveUserProfile(up);
}
else
{
return View(model);
}
}
return RedirectToAction("Index", "Admin");
}
代码仍然需要大量工作,但我无法摆脱在发布时将模型返回控制器。我也尝试返回UserProfileViewModel而不是整个列表。
谁能说出我做错了什么?
谢谢!
你有很多无效的html,包括form
元素作为tr
元素的子元素和重复的id
属性。如果要回发UserProfileListModel
则需要单个form
元素,并使用EditorTemplate
或for
循环(不是foreach
)来呈现控件,以便使用索引器正确命名它们。
您还尝试将下拉列表绑定到复杂对象(例如UserProfile
、Role
等)。 <select>
元素(和所有表单控件)仅回发键/值对,因此您需要绑定到值类型(例如 UserProfile.UserId
)。
您的 SaveUserChanges()
post 方法也在尝试访问 UserProfile
的属性,但您甚至没有以回发到此方法的形式(例如 UserId = upvm.UserProfile.UserId, UserEmail = upvm.UserProfile.UserName, ...
)的 UserProfile
属性的控件,因此它们将始终为 null。
POST 方法中绑定属性,如下所示:
public ActionResult Create([Bind(Include = "Id,Subject,Text,IsImportant")] Announcment announcment) {... }
所以它将是:
public ActionResult SaveUserChanges([Bind(Include = "UserProfile,Role,UserTeam,UserScope")]UserProfileListModel model)
您是否指定了针对 HTTP Post 的操作方法?并更改您的操作方法以接受 UserProfileViewModels。
[HttpPost]
public ActionResult SaveUserChanges(UserProfileViewModels model)
{
您也只回发一个模型:UserProfileViewModels。您的表单位于 foreach 循环中,因此每个 UserProfileViewModels 都有自己的窗体。如果要更改它以回发您的用户配置文件列表模型,请移动
@{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))
在你的前方之外。