Ваше мнение не имеет form
тег
@model MyBlogger.ViewModel.PostsViewModel
@{
ViewBag.Title = "EditPostTag";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>EditPostTag</h2>
@using (Html.BeginForm()) // add this
{
....
}
Редактировать (далее в комментарии и некоторые недоразумения О.П.)
Используя представление модель, как вы это сделали, всегда хорошая практика, но вы не используют его, продолжая использовать 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; }
}
Side Примечание: Его немного непонятно, почему вы позволяете пользователю выбрать другой пользователь должен быть связан с 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" />
}
Side Примечание: Так как параметр вашего метода называется id
, значение из id
будет добавлено к параметрам маршрута, поэтому нет необходимости добавлять скрытый ввод для модели вида ID
(DefaultModelBinder
считывает значения маршрута в дополнение к значениям формы, поэтому свойство модели ID
будет правильно привязано (до 12
в вашем случае)
Где находится тег