您的视图没有form 标签
@model MyBlogger.ViewModel.PostsViewModel
@{
ViewBag.Title = "EditPostTag";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>EditPostTag</h2>
@using (Html.BeginForm()) // add this
{
....
}
编辑(进一步说明 cmets 和 OP 的一些误解)
像您所做的那样使用视图模型始终是一种很好的做法,但是您并没有通过继续使用ViewBag 并使用它来保存数据模型而不是仅包含视图所需的属性来利用它。我推荐它是
public class PostViewModel // its for a single post - not plural?
{
public int ID { get; set; }
[Required(ErrorMessage = "Please enter a title")]
public string Title { get; set; }
[Display(Name = "Tags")] // plus [Required] is at least one tag must be selected
public List<int> SelectedTags { get; set; }
public SelectList TagsList { get; set; }
// Its unclear if you really need the following 2 properties (see notes)
[Display(Name = "User")]
[Required(ErrorMessage = "Please select a user")]
public int UserID { get; set; }
public SelectList UserList { get; set; }
}
旁注:有点不清楚为什么您允许用户选择另一个用户与Post 对象关联。我怀疑当您保存 Post 时,您应该只是在控制器的 POST 方法中分配当前用户
您的控制器方法将是(假设这是PostController)
public ActionResult Edit(int id)
{
Post post = db.Posts.Include(i => i.Tags).FirstOrDefault(i => i.Id == id); // First() will throw an exception is the item is not found
if (post == null) { return HttpNotFound(); }
PostViewModel model = new PostViewModel()
{
ID = post.ID,
Title = post.Title,
SelectedTags = post.Tags.Select(t => t.Id)
}; // include UserId property?
ConfigureEditModel(model);
return View(model);
}
[HttpPost]
public ActionResult Edit(PostViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureEditModel(model);
return View(model);
}
// map your view model to a data model, save it and redirect
}
private void ConfigureEditModel(PostViewModel model)
{
model.TagsList = new SelectList(db.Tags, "Id", "Name");
model.UserList = new BlogUsers(db.Tags, "UserID", "Email"); // ??
}
旁注:SelectList 或 IEnumerable<SelectListItem> 都可以接受(我发现 SelectList 更容易阅读,但它会慢一到两毫秒,因为它使用反射来生成 IEnumerable<SelectListItem>),但使用第 4 个参数,就像您对 new SelectList(db.BlogUsers, "UserID", "Email", postsViewModel.posts.Id); 所做的那样 - 您与属性的绑定和所选项目将是该属性的值,因此尝试设置 Selected 属性将被忽略)
最后是视图(简化为只显示没有 html 属性的助手)
@model MyBlogger.ViewModel.PostViewModel
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
// @Html.HiddenFor(model => model.posts.Id) not required
@Html.LabelFor(m => m.Title)
@Html.TextBoxFor(m => m.Title)
@Html.ValidationMessageFor(m => m.Title)
// Is the UserId property required?
@Html.LabelFor(m => m.UserID)
@Html.DropDownListFor(m => m.UserID, Model.UserList, "Please select")
@Html.ValidationMessageFor(m => m.UserID)
@Html.LabelFor(model => model.SelectedTags)
@Html.ListBoxFor(m => m.SelectedTags, Model.TagsList)
// Add ValidationMessageFor() if at least one should be selected
<input type="submit" value="Save" class="btn btn-default" />
}
旁注:由于您的方法的参数名为id,id 属性的值将添加到路由参数中,因此无需为视图模型添加隐藏输入ID属性(DefaultModelBinder 读取除了表单值之外的路由值,因此视图模型ID 属性将被正确绑定(在您的情况下为12)