ASP.NET MVC 中多对多关系的 CheckBoxList
CheckBoxList for many-to-many relationship in ASP.NET MVC
我正在尝试在 MVC 中为多对多关系(文章 - 类别)实现一个复选框列表。我试过这个,但我不工作。有谁知道获得它的不同且正确的方法。
在域模型中:
public class Article
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Title { get; set; }
[Required]
public string Body { get; set; }
[Required]
public DateTime DateCreated { get; set; }
[Required]
[StringLength(255)]
public string Author { get; set; }
public ICollection<ArticleComment> Comments { get; set; }
public ICollection<Category> Categories { get; set; }
}
在视图模型中:
public class ArticlesCategoriesViewModel
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
[UIHint("tinymce_jquery_full"), AllowHtml]
public string Body { get; set; }
[Required]
[DataType(DataType.Date)]
[Display(Name = "Publication Date")]
public DateTime DateCreated { get; set; }
[Required]
public string Author { get; set; }
public IEnumerable<CategoriesViewModel> Categories { get; set; }
public IEnumerable<CategoriesViewModel> AllCategories { get; set; }
public string[] PostedCategories { get; set; }
}
在控制器中:
public ActionResult Edit(int id)
{
//Return article with its categories
Article articleToEdit = _repo.GetArticleCategories(id);
Mapper.CreateMap<Article, ArticlesCategoriesViewModel>();
Mapper.CreateMap<Category, CategoriesViewModel>();
ArticlesCategoriesViewModel article = Mapper.Map<Article, ArticlesCategoriesViewModel>(articleToEdit);
//Return all categories
IEnumerable<Category> allCategories = _repo.GetAllCategories();
IEnumerable<CategoriesViewModel> AllCategories = Mapper.Map <IEnumerable<Category>, IEnumerable<CategoriesViewModel>>(allCategories);
article.AllCategories = AllCategories;
if (articleToEdit == null)
{
return HttpNotFound();
}
return View(article);
}
在视图模型中:
<ul>
@foreach (var g in Model.AllCategories)
{
<li>
<input type="checkbox" name="PostedCategories" value="@g.Id" id="@g.Id"
@{if (Model.Categories.FirstOrDefault(h => h.Id == g.Id) != null) { <text> checked='checked' </text> } } />
<label for="@g.Id">@g.Name</label>
</li>
}
</ul>
它可以显示文章的所有类别,但是当我提交到 POST 我选择的新类别时,我的模型无效。
这是我的Post方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Title,Body,DateCreated,Author,PostedCategories")]ArticlesCategoriesViewModel articleToEdit)
{
if (ModelState.IsValid)
{
Mapper.CreateMap<ArticlesCategoriesViewModel, Article>();
Article article = Mapper.Map<ArticlesCategoriesViewModel, Article>(articleToEdit);
if (_repo.EditArticle(article) && _repo.Save())
{
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "One or more erros were found. Operation was not valid.");
return View(articleToEdit);
}
}
ModelState.AddModelError("", "One or more erros were found. Model-binding operation was not valid.");
return View(articleToEdit);
}
当 MVC 模型数据绑定尝试匹配数据时出现空引用错误,显然是在它匹配我的模型视图的集合 "AllCategories"、"Categories" 时发生的。
如果有任何帮助,我将不胜感激。
您应该为 Category
使用视图模型,它具有描述视图 display/edit 的属性的属性
public class CategoryVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class ArticlesCategoriesViewModel
{
public int Id { get; set; }
....
public string Author { get; set; }
List<CategoryVM> Categories { get; set; }
}
查看
for(int i = 0; i < Model.Categories.Count; i++)
{
@Html.CheckBoxFor(m => m.Categories[i].IsSelected)
@Html.LabelFor(m => m.Categories[i].IsSelected, Model.Categories[i].Name)
@Html.HiddenFor(m => m.Categories[i].ID)
@Html.HiddenFor(m => m.Categories[i].Name)
}
在 GET 方法中,根据 id 初始化 ArticlesCategoriesViewModel
,并为每个可用类别添加一个 CategoryVM,并根据已分配给文章的类别设置 IsSelected 属性。在 POST 方法中,您可以使用 var selectedCategories = articleToEdit.Categories.Where(c => c.IsSelected)
.
获取所选类别
您还应该删除 [Bind(Include="..")]
属性。视图模型仅表示您在视图中 display/edit 的内容,因此没有必要,因为您不应排除任何属性。
我正在尝试在 MVC 中为多对多关系(文章 - 类别)实现一个复选框列表。我试过这个,但我不工作。有谁知道获得它的不同且正确的方法。
在域模型中:
public class Article
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Title { get; set; }
[Required]
public string Body { get; set; }
[Required]
public DateTime DateCreated { get; set; }
[Required]
[StringLength(255)]
public string Author { get; set; }
public ICollection<ArticleComment> Comments { get; set; }
public ICollection<Category> Categories { get; set; }
}
在视图模型中:
public class ArticlesCategoriesViewModel
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
[UIHint("tinymce_jquery_full"), AllowHtml]
public string Body { get; set; }
[Required]
[DataType(DataType.Date)]
[Display(Name = "Publication Date")]
public DateTime DateCreated { get; set; }
[Required]
public string Author { get; set; }
public IEnumerable<CategoriesViewModel> Categories { get; set; }
public IEnumerable<CategoriesViewModel> AllCategories { get; set; }
public string[] PostedCategories { get; set; }
}
在控制器中:
public ActionResult Edit(int id)
{
//Return article with its categories
Article articleToEdit = _repo.GetArticleCategories(id);
Mapper.CreateMap<Article, ArticlesCategoriesViewModel>();
Mapper.CreateMap<Category, CategoriesViewModel>();
ArticlesCategoriesViewModel article = Mapper.Map<Article, ArticlesCategoriesViewModel>(articleToEdit);
//Return all categories
IEnumerable<Category> allCategories = _repo.GetAllCategories();
IEnumerable<CategoriesViewModel> AllCategories = Mapper.Map <IEnumerable<Category>, IEnumerable<CategoriesViewModel>>(allCategories);
article.AllCategories = AllCategories;
if (articleToEdit == null)
{
return HttpNotFound();
}
return View(article);
}
在视图模型中:
<ul>
@foreach (var g in Model.AllCategories)
{
<li>
<input type="checkbox" name="PostedCategories" value="@g.Id" id="@g.Id"
@{if (Model.Categories.FirstOrDefault(h => h.Id == g.Id) != null) { <text> checked='checked' </text> } } />
<label for="@g.Id">@g.Name</label>
</li>
}
</ul>
它可以显示文章的所有类别,但是当我提交到 POST 我选择的新类别时,我的模型无效。
这是我的Post方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Title,Body,DateCreated,Author,PostedCategories")]ArticlesCategoriesViewModel articleToEdit)
{
if (ModelState.IsValid)
{
Mapper.CreateMap<ArticlesCategoriesViewModel, Article>();
Article article = Mapper.Map<ArticlesCategoriesViewModel, Article>(articleToEdit);
if (_repo.EditArticle(article) && _repo.Save())
{
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "One or more erros were found. Operation was not valid.");
return View(articleToEdit);
}
}
ModelState.AddModelError("", "One or more erros were found. Model-binding operation was not valid.");
return View(articleToEdit);
}
当 MVC 模型数据绑定尝试匹配数据时出现空引用错误,显然是在它匹配我的模型视图的集合 "AllCategories"、"Categories" 时发生的。 如果有任何帮助,我将不胜感激。
您应该为 Category
使用视图模型,它具有描述视图 display/edit 的属性的属性
public class CategoryVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class ArticlesCategoriesViewModel
{
public int Id { get; set; }
....
public string Author { get; set; }
List<CategoryVM> Categories { get; set; }
}
查看
for(int i = 0; i < Model.Categories.Count; i++)
{
@Html.CheckBoxFor(m => m.Categories[i].IsSelected)
@Html.LabelFor(m => m.Categories[i].IsSelected, Model.Categories[i].Name)
@Html.HiddenFor(m => m.Categories[i].ID)
@Html.HiddenFor(m => m.Categories[i].Name)
}
在 GET 方法中,根据 id 初始化 ArticlesCategoriesViewModel
,并为每个可用类别添加一个 CategoryVM,并根据已分配给文章的类别设置 IsSelected 属性。在 POST 方法中,您可以使用 var selectedCategories = articleToEdit.Categories.Where(c => c.IsSelected)
.
您还应该删除 [Bind(Include="..")]
属性。视图模型仅表示您在视图中 display/edit 的内容,因此没有必要,因为您不应排除任何属性。