mvc按钮在单击时不会执行任何操作



所以我修复了之前在这里问的问题,现在我得到了我想要的东西,但当我点击保存时,它什么都没做?没有错误或回发,也没有保存到数据库?在我看来,这个按钮没有任何作用?

在我的EF模型中,我与Post和Tag有很多对很多的关系。我正试图为标签分配一个帖子。我一直在学习这个教程。但是,当我单击"保存"时,该按钮不起任何作用。

PostController:

public ActionResult EditPostTag(int id = 12) // hardcoded the post for now
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var postsViewModel = new PostsViewModel
{
posts = db.Posts.Include(i => i.Tags).First(i => i.Id == id),
};
if (postsViewModel.posts == null)
return HttpNotFound();
var tagsList = db.Tags.ToList();
postsViewModel.Tags = tagsList.Select(o => new SelectListItem
{
Text = o.Name,
Value = o.Id.ToString()
});
ViewBag.UserID =
new SelectList(db.BlogUsers, "UserID", "Email", postsViewModel.posts.Id);
return View(postsViewModel);
} 

您的视图没有form标记

@model MyBlogger.ViewModel.PostsViewModel
@{
ViewBag.Title = "EditPostTag";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>EditPostTag</h2>
@using (Html.BeginForm()) // add this
{
....
}

编辑(进一步评论和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"); // ??
}

附带说明:SelectListIEnumerable<SelectListItem>都是可以接受的(我发现SelectList更容易读取,但它慢了一两毫秒,因为它使用反射来生成IEnumerable<SelectListItem>),但使用第四个参数没有意义,就像使用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)

最新更新