如何在 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.

的列表

按照以下步骤操作;

  1. 创建一个视图模型,我们将在其中绑定名称和 ID 列表。
public class ProductCategoryCreateViewModel {
   public string Name {get;set;}
   public List<int> ProductIds {get;set;}
}
  1. 控制器使用下面的代码,见评论。
[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");
}
  1. name="ProductIds" 添加到 select 标签。删除 for 属性。
<select name="ProductIds" id="Products" class="form-control" multiple>
   ...        
</select>