IEnumerable<Model> 返回 null
IEnumerable<Model> returning null
我很难通过 IEnumerable
作为模型。数据正在填充一页上的表单 - 并且这样做是正确的。提交后模型 returns 为空。
我在这方面看到了各种 post,它们大多引用命名约定,因此我尝试了不同的参数命名方法,以避免模型绑定中的任何混淆。
我也尝试过各种模型和助手来尝试传递数据,结果都是一样的。
当前实施:
型号:
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
SNIP
<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");
}
代码仍然需要大量工作,但我无法在 post 上将模型返回控制器。我还尝试返回 UserProfileViewModel 而不是整个列表。
谁能告诉我哪里做错了?
谢谢!
您可能需要在 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)
{
您也只 post返回一个模型:UserProfileViewModels。
您的 foreach 循环中有您的表单,因此每个 UserProfileViewModels 都有自己的表单。如果您想将其更改为 post 返回您的 UserProfileListModel,请移动
@{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))
在你的 foreach 之外。
您有很多无效的 html,包括作为 tr
元素的子元素的 form
元素和重复的 id
属性。如果你想 post 返回 UserProfileListModel
那么你需要一个 form
元素并使用 EditorTemplate
或 for
循环(而不是 foreach
)呈现控件,以便使用索引器正确命名它们。
您还试图将下拉列表绑定到复杂对象(例如 UserProfile
、Role
等)。 <select>
元素(和所有表单控件)仅 post 返回 key/value 对,因此您需要绑定到值类型(例如 UserProfile.UserId
)。
您的 SaveUserChanges()
post 方法也在尝试访问 UserProfile
的属性,但您甚至没有以 post 返回到此方法(例如 UserId = upvm.UserProfile.UserId, UserEmail = upvm.UserProfile.UserName, ...
),因此它们将始终为空。
我很难通过 IEnumerable
作为模型。数据正在填充一页上的表单 - 并且这样做是正确的。提交后模型 returns 为空。
我在这方面看到了各种 post,它们大多引用命名约定,因此我尝试了不同的参数命名方法,以避免模型绑定中的任何混淆。
我也尝试过各种模型和助手来尝试传递数据,结果都是一样的。
当前实施:
型号:
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
SNIP
<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");
}
代码仍然需要大量工作,但我无法在 post 上将模型返回控制器。我还尝试返回 UserProfileViewModel 而不是整个列表。
谁能告诉我哪里做错了?
谢谢!
您可能需要在 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)
{
您也只 post返回一个模型:UserProfileViewModels。 您的 foreach 循环中有您的表单,因此每个 UserProfileViewModels 都有自己的表单。如果您想将其更改为 post 返回您的 UserProfileListModel,请移动
@{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))
在你的 foreach 之外。
您有很多无效的 html,包括作为 tr
元素的子元素的 form
元素和重复的 id
属性。如果你想 post 返回 UserProfileListModel
那么你需要一个 form
元素并使用 EditorTemplate
或 for
循环(而不是 foreach
)呈现控件,以便使用索引器正确命名它们。
您还试图将下拉列表绑定到复杂对象(例如 UserProfile
、Role
等)。 <select>
元素(和所有表单控件)仅 post 返回 key/value 对,因此您需要绑定到值类型(例如 UserProfile.UserId
)。
您的 SaveUserChanges()
post 方法也在尝试访问 UserProfile
的属性,但您甚至没有以 post 返回到此方法(例如 UserId = upvm.UserProfile.UserId, UserEmail = upvm.UserProfile.UserName, ...
),因此它们将始终为空。