包含[多对多关系的部分视图]的编辑视图的 MVC 问题
MVC problem with view of Edit that contain [partial view from relation many to many]
我尝试创建一个图书馆系统,其中在类别中与书籍有很多关系,我需要在我的书籍编辑视图中放入实体的部分视图,有人可以帮助我吗?
我的编辑视图:
@model MVC_Library.Models.Book
@{
ViewData["Title"] = "Edit";
BookCategory teste = ViewBag.testeview;
}
<h1>Edit</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="BookId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BasePrice" class="control-label"></label>
<input asp-for="BasePrice" class="form-control" />
<span asp-validation-for="BasePrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Quantity" class="control-label"></label>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishingCompanyId" class="control-label"></label>
<select asp-for="PublishingCompanyId" class="form-control" asp-items="ViewBag.PublishingCompanyId"></select>
<span asp-validation-for="PublishingCompanyId" class="text-danger"></span>
</div>
<div>
@Html.Partial("_EditBookCategory", teste)
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
我的部分观点行得通(但以这种方式只是预 select 一个类别项目)
@model MVC_Library.Models.BookCategory
<div class="row">
<div class="col-md-12">
<label asp-for="CategoryId" class="control-label"></label>
<select multiple asp-for="CategoryId" class="form-control" name = "BookCategory[]" asp-items="ViewBag.SelectedCategory"></select>
</div>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
和我的控制器编辑部分
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var book = await _context.Books.FindAsync(id);
if (book == null)
{
return NotFound();
}
List<BookCategory> bookCategory = _context.BookCategories.Where(e => e.BookId == id).ToList();
ViewData["PublishingCompanyId"] = new SelectList(_context.PublishingCompanies, "PublishingCompanyId", "PublishingCompanyName", book.PublishingCompanyId);
//this is what i try for try return mutiple category select (don't work with this viewbag)
/* ViewBag.SelectedCategory = new MultiSelectList(_context.Categories.ToList(), "CategoryId", "CategoryName", bookCategory); */
//this viewbag return only one category selected but work
ViewBag.testeview = bookCategory.First();
return View(book);
}
刚刚selected(第一个),但是想return全部。如果可能,需要帮助。
如果你想显示所有相关类别selected:
- 确保
asp-for="CategoryId"
这里的 CategoryId
应该是 int[]
或 string[]
的类型。 或 只需删除 asp-for
标记助手,因为您在此处添加了 name="BookCategory[]"
,它将覆盖 asp-for
生成的名称属性。当你提交表单时,无论你是否添加asp-for
,你的操作总是需要包含一个名为BookCategory[]
的参数。
此外 BookCategory[]
不是正确的名称,数组中没有索引,它应该是 BookCategory
或任何其他名称,并且操作中的参数名称应该是 int[]
类型或string[]
。猜测您可能希望将 selected 值与列表模型 BookCategory
的 CategoryId 相匹配。对于 multiple select.
是不可接受的
确保 MultiSelectList
中的最后一个参数应为 int[]
或 string[]
。根据您的代码,MultiSelectList
中的 dataValueField
匹配 CategoryId
属性,因此您的最后一个参数应该类似于 bookCategory.Select(a=>a.CategoryId).ToList()
.
ViewBag.SelectedCategory = new MultiSelectList(_context.Categories.ToList(), "CategoryId", "CategoryName",
bookCategory.Select(a=>a.CategoryId).ToList());
不用ViewBag.testeview
,改成如下:
@Html.Partial("_EditBookCategory", new BookCategory())
整个工作演示应该是这样的:
型号:
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime PublishDate { get; set; }
public int BasePrice { get; set; }
public int Quantity { get; set; }
public int PublishingCompanyId { get; set; }
public List<BookCategory> BookCategory { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public List<BookCategory> BookCategory { get; set; }
}
public class BookCategory
{
public int CategoryId { get; set; }
public int BookId { get; set; }
public Category Category { get; set; }
public Book Book { get; set; }
}
查看:
@model Book
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="BookId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BasePrice" class="control-label"></label>
<input asp-for="BasePrice" class="form-control" />
<span asp-validation-for="BasePrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Quantity" class="control-label"></label>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishingCompanyId" class="control-label"></label>
<select asp-for="PublishingCompanyId" class="form-control" asp-items="ViewBag.PublishingCompanyId"></select>
<span asp-validation-for="PublishingCompanyId" class="text-danger"></span>
</div>
<div>
//change here....
@Html.Partial("_EditBookCategory", new BookCategory())
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
局部视图:
@model BookCategory
<div class="row">
<div class="col-md-12">
<label asp-for="CategoryId" class="control-label"></label>
<select multiple class="form-control" name="CategoryId" asp-items="ViewBag.SelectedCategory"></select>
</div>
</div>
控制器:
注意:我只是hard-coded数据,因为方便测试,和你从数据库中获取数据是一样的。你只需要像我的评论所说的那样改变,其他代码不需要像我所做的那样改变。
public IActionResult Edit(int? id)
{
var book = new Book()
{
BookId = 1,
PublishDate = DateTime.Now,
Author = "a1",
BasePrice = 34,
PublishingCompanyId = 1,
Quantity = 23,
Title = "aa"
};
List<BookCategory> bookCategory = new List<BookCategory>()
{
new BookCategory(){BookId=1,CategoryId=1},
new BookCategory(){BookId=2,CategoryId=1},
new BookCategory(){BookId=2,CategoryId=3}
};
ViewData["PublishingCompanyId"] = new List<SelectListItem>() {
new SelectListItem() { Value = "1", Text = "Elementos1" },
new SelectListItem() { Value = "2", Text = "Elementos2" },
new SelectListItem() { Value = "3", Text = "Elementos3" }
};
var c = new List<Category>()
{
new Category(){CategoryId=1,Name="aa"},
new Category(){CategoryId=2,Name="bb"},
new Category(){CategoryId=3,Name="cc"}
};
//change here....
ViewBag.SelectedCategory = new MultiSelectList(c, "CategoryId", "Name", bookCategory.Select(a=>a.CategoryId).ToList());
//ViewBag.testeview = bookCategory.First();
return View(book);
}
[HttpPost]
public IActionResult Edit(int? id,Book book, int[] CategoryId)
{
//do your stuff......
return View();
}
结果:
如何选择多个选项,你只需要按住Ctrl
键的同时点击选项即可。
我尝试创建一个图书馆系统,其中在类别中与书籍有很多关系,我需要在我的书籍编辑视图中放入实体的部分视图,有人可以帮助我吗?
我的编辑视图:
@model MVC_Library.Models.Book
@{
ViewData["Title"] = "Edit";
BookCategory teste = ViewBag.testeview;
}
<h1>Edit</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="BookId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BasePrice" class="control-label"></label>
<input asp-for="BasePrice" class="form-control" />
<span asp-validation-for="BasePrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Quantity" class="control-label"></label>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishingCompanyId" class="control-label"></label>
<select asp-for="PublishingCompanyId" class="form-control" asp-items="ViewBag.PublishingCompanyId"></select>
<span asp-validation-for="PublishingCompanyId" class="text-danger"></span>
</div>
<div>
@Html.Partial("_EditBookCategory", teste)
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
我的部分观点行得通(但以这种方式只是预 select 一个类别项目)
@model MVC_Library.Models.BookCategory
<div class="row">
<div class="col-md-12">
<label asp-for="CategoryId" class="control-label"></label>
<select multiple asp-for="CategoryId" class="form-control" name = "BookCategory[]" asp-items="ViewBag.SelectedCategory"></select>
</div>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
和我的控制器编辑部分
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var book = await _context.Books.FindAsync(id);
if (book == null)
{
return NotFound();
}
List<BookCategory> bookCategory = _context.BookCategories.Where(e => e.BookId == id).ToList();
ViewData["PublishingCompanyId"] = new SelectList(_context.PublishingCompanies, "PublishingCompanyId", "PublishingCompanyName", book.PublishingCompanyId);
//this is what i try for try return mutiple category select (don't work with this viewbag)
/* ViewBag.SelectedCategory = new MultiSelectList(_context.Categories.ToList(), "CategoryId", "CategoryName", bookCategory); */
//this viewbag return only one category selected but work
ViewBag.testeview = bookCategory.First();
return View(book);
}
刚刚selected(第一个),但是想return全部。如果可能,需要帮助。
如果你想显示所有相关类别selected:
- 确保
asp-for="CategoryId"
这里的CategoryId
应该是int[]
或string[]
的类型。 或 只需删除asp-for
标记助手,因为您在此处添加了name="BookCategory[]"
,它将覆盖asp-for
生成的名称属性。当你提交表单时,无论你是否添加asp-for
,你的操作总是需要包含一个名为BookCategory[]
的参数。
此外 BookCategory[]
不是正确的名称,数组中没有索引,它应该是 BookCategory
或任何其他名称,并且操作中的参数名称应该是 int[]
类型或string[]
。猜测您可能希望将 selected 值与列表模型 BookCategory
的 CategoryId 相匹配。对于 multiple select.
确保
MultiSelectList
中的最后一个参数应为int[]
或string[]
。根据您的代码,MultiSelectList
中的dataValueField
匹配CategoryId
属性,因此您的最后一个参数应该类似于bookCategory.Select(a=>a.CategoryId).ToList()
.ViewBag.SelectedCategory = new MultiSelectList(_context.Categories.ToList(), "CategoryId", "CategoryName", bookCategory.Select(a=>a.CategoryId).ToList());
不用
ViewBag.testeview
,改成如下:@Html.Partial("_EditBookCategory", new BookCategory())
整个工作演示应该是这样的:
型号:
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime PublishDate { get; set; }
public int BasePrice { get; set; }
public int Quantity { get; set; }
public int PublishingCompanyId { get; set; }
public List<BookCategory> BookCategory { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public List<BookCategory> BookCategory { get; set; }
}
public class BookCategory
{
public int CategoryId { get; set; }
public int BookId { get; set; }
public Category Category { get; set; }
public Book Book { get; set; }
}
查看:
@model Book
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="BookId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BasePrice" class="control-label"></label>
<input asp-for="BasePrice" class="form-control" />
<span asp-validation-for="BasePrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Quantity" class="control-label"></label>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishingCompanyId" class="control-label"></label>
<select asp-for="PublishingCompanyId" class="form-control" asp-items="ViewBag.PublishingCompanyId"></select>
<span asp-validation-for="PublishingCompanyId" class="text-danger"></span>
</div>
<div>
//change here....
@Html.Partial("_EditBookCategory", new BookCategory())
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
局部视图:
@model BookCategory
<div class="row">
<div class="col-md-12">
<label asp-for="CategoryId" class="control-label"></label>
<select multiple class="form-control" name="CategoryId" asp-items="ViewBag.SelectedCategory"></select>
</div>
</div>
控制器:
注意:我只是hard-coded数据,因为方便测试,和你从数据库中获取数据是一样的。你只需要像我的评论所说的那样改变,其他代码不需要像我所做的那样改变。
public IActionResult Edit(int? id)
{
var book = new Book()
{
BookId = 1,
PublishDate = DateTime.Now,
Author = "a1",
BasePrice = 34,
PublishingCompanyId = 1,
Quantity = 23,
Title = "aa"
};
List<BookCategory> bookCategory = new List<BookCategory>()
{
new BookCategory(){BookId=1,CategoryId=1},
new BookCategory(){BookId=2,CategoryId=1},
new BookCategory(){BookId=2,CategoryId=3}
};
ViewData["PublishingCompanyId"] = new List<SelectListItem>() {
new SelectListItem() { Value = "1", Text = "Elementos1" },
new SelectListItem() { Value = "2", Text = "Elementos2" },
new SelectListItem() { Value = "3", Text = "Elementos3" }
};
var c = new List<Category>()
{
new Category(){CategoryId=1,Name="aa"},
new Category(){CategoryId=2,Name="bb"},
new Category(){CategoryId=3,Name="cc"}
};
//change here....
ViewBag.SelectedCategory = new MultiSelectList(c, "CategoryId", "Name", bookCategory.Select(a=>a.CategoryId).ToList());
//ViewBag.testeview = bookCategory.First();
return View(book);
}
[HttpPost]
public IActionResult Edit(int? id,Book book, int[] CategoryId)
{
//do your stuff......
return View();
}
结果:
如何选择多个选项,你只需要按住Ctrl
键的同时点击选项即可。