如何在 ASP.NET 核心 MVC 中使用 TagHelpers 传递多个 select 数据
How to pass multiple select data with TagHelpers in ASP.NET Core MVC
我的问题是:我无法将数组数据从视图(HTML-select 组件多模式)传递到存在一对多关系的控制器。
我尝试使用 Microsoft.AspNetCore.Mvc.TagHelpers
作为视图。
请看MVC设计(我简化了):
型号
public class Product
{
[Key]
public int id { get; set; }
public string? Name { get; set; }
[ForeignKey("ProductCategory")]
public int Categoryid { get; set; }
public ProductCategory ProductCategory{ get; set; }
}
public class ProductCategory
{
[Key]
public int id { get; set; }
public string Name { get; set; }
public IList<Product> Products{ get; set; }
}
查看
@using Microsoft.EntityFrameworkCore
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model ProjectCategory
<form method="post">
<div class="container-fluid">
<div class="row">
<div class="col-12 col-lg-6 pt-3">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control"/>
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-12 col-lg-6 pt-3">
<label asp-for="Products"></label><br/>
<select id="Products" asp-for="Accounts" class="form-control" multiple>
<option value="">Please select products...</option>
@{
Context c = new Context();
var products = c.Products.ToList();
}
@foreach(var r in products){<option value="@r.id">@r.Name</option>}
</select>
<span asp-validation-for="Products" class="text-danger"></span>
</div>
<div class="col-12" >
<br/> <button type="submit"> Create</button>
</div>
</div>
</div>
</form>
<script>
// some js code to handle multiple select.. (selectize.js used)
</script>
控制器
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(ProductCategory productcategory)
{
if (!ModelState.IsValid)
return View(productcategory);
// Problem is right here.
// in debug mode I see, productcategory.Products Count : 0
// I could not pass Products from the view to controller
Context c = new Context();
c.ProductCategories.Add(productcategory);
c.SaveChanges();
return RedirectToAction("Index");
}
我搜索过,我看到了将多个 select 项传递给控制器的示例,但这些示例只是一个数组,没有像我的示例那样一对多传递模型对象的模型。
怎么做?
在您的 select 中,选项字段值为 id
,因此您应该期待一个 Product.id
.
的列表
按照以下步骤操作;
- 创建一个视图模型,我们将在其中绑定名称和 ID 列表。
public class ProductCategoryCreateViewModel {
public string Name {get;set;}
public List<int> ProductIds {get;set;}
}
- 控制器使用下面的代码,见评论。
[HttpPost]
[ValidateAntiForgeryToken]
// bind the form data to the view model
public IActionResult Create(ProductCategoryCreateViewModel viewModel)
{
if (!ModelState.IsValid)
return RedirectToAction("Create");
Context c = new Context();
// make a new ProductCategory using the ViewModel
ProductCategory newCategory = new ProductCategory();
// assign name to new category
newCategory.Name = viewModel.Name;
// save the category first so it will generate a new category id
c.ProductCategories.Add(newCategory);
c.SaveChanges();
// loop through all product ids selected, and update them with the newcategoryid
foreach(var id in viewModel.ProductIds){
// load the product
var updateProduct = c.Products.FirstOrDefault(p=>p.id == id);
if(updateProduct != null){
// if product is found, update the category id
updateProduct.Categoryid = newCategory.id;
c.SaveChanges();
}
}
return RedirectToAction("Index");
}
- 将
name="ProductIds"
添加到 select 标签。删除 for
属性。
<select name="ProductIds" id="Products" class="form-control" multiple>
...
</select>
我的问题是:我无法将数组数据从视图(HTML-select 组件多模式)传递到存在一对多关系的控制器。
我尝试使用 Microsoft.AspNetCore.Mvc.TagHelpers
作为视图。
请看MVC设计(我简化了):
型号
public class Product
{
[Key]
public int id { get; set; }
public string? Name { get; set; }
[ForeignKey("ProductCategory")]
public int Categoryid { get; set; }
public ProductCategory ProductCategory{ get; set; }
}
public class ProductCategory
{
[Key]
public int id { get; set; }
public string Name { get; set; }
public IList<Product> Products{ get; set; }
}
查看
@using Microsoft.EntityFrameworkCore
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model ProjectCategory
<form method="post">
<div class="container-fluid">
<div class="row">
<div class="col-12 col-lg-6 pt-3">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control"/>
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-12 col-lg-6 pt-3">
<label asp-for="Products"></label><br/>
<select id="Products" asp-for="Accounts" class="form-control" multiple>
<option value="">Please select products...</option>
@{
Context c = new Context();
var products = c.Products.ToList();
}
@foreach(var r in products){<option value="@r.id">@r.Name</option>}
</select>
<span asp-validation-for="Products" class="text-danger"></span>
</div>
<div class="col-12" >
<br/> <button type="submit"> Create</button>
</div>
</div>
</div>
</form>
<script>
// some js code to handle multiple select.. (selectize.js used)
</script>
控制器
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(ProductCategory productcategory)
{
if (!ModelState.IsValid)
return View(productcategory);
// Problem is right here.
// in debug mode I see, productcategory.Products Count : 0
// I could not pass Products from the view to controller
Context c = new Context();
c.ProductCategories.Add(productcategory);
c.SaveChanges();
return RedirectToAction("Index");
}
我搜索过,我看到了将多个 select 项传递给控制器的示例,但这些示例只是一个数组,没有像我的示例那样一对多传递模型对象的模型。
怎么做?
在您的 select 中,选项字段值为 id
,因此您应该期待一个 Product.id
.
按照以下步骤操作;
- 创建一个视图模型,我们将在其中绑定名称和 ID 列表。
public class ProductCategoryCreateViewModel {
public string Name {get;set;}
public List<int> ProductIds {get;set;}
}
- 控制器使用下面的代码,见评论。
[HttpPost]
[ValidateAntiForgeryToken]
// bind the form data to the view model
public IActionResult Create(ProductCategoryCreateViewModel viewModel)
{
if (!ModelState.IsValid)
return RedirectToAction("Create");
Context c = new Context();
// make a new ProductCategory using the ViewModel
ProductCategory newCategory = new ProductCategory();
// assign name to new category
newCategory.Name = viewModel.Name;
// save the category first so it will generate a new category id
c.ProductCategories.Add(newCategory);
c.SaveChanges();
// loop through all product ids selected, and update them with the newcategoryid
foreach(var id in viewModel.ProductIds){
// load the product
var updateProduct = c.Products.FirstOrDefault(p=>p.id == id);
if(updateProduct != null){
// if product is found, update the category id
updateProduct.Categoryid = newCategory.id;
c.SaveChanges();
}
}
return RedirectToAction("Index");
}
- 将
name="ProductIds"
添加到 select 标签。删除for
属性。
<select name="ProductIds" id="Products" class="form-control" multiple>
...
</select>