【问题标题】:How to pass multiple select data with TagHelpers in ASP.NET Core MVC如何在 ASP.NET Core MVC 中使用 TagHelpers 传递多选数据
【发布时间】:2022-06-30 19:14:51
【问题描述】:

我的问题是:我无法将数组数据从视图(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");
}

我搜索了,我看到了将多个选择项传递给控制器​​的示例,但这些示例只是一个数组,没有像我的示例这样一对多传递模型对象的模型。

怎么做?

【问题讨论】:

    标签: c# entity-framework-core asp.net-core-mvc html-select asp.net-core-tag-helpers


    【解决方案1】:

    在您的选择中,选项字段的值为id,因此您应该期待Product.id 的列表。

    按照以下步骤操作;

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

    【讨论】:

    • 我想我理解你的方法。我应该创建一个 ViewModel。但是知道如何从这里的 View(例如 List ProductIds)中传递一个数组作为参数吗?您能否将 View 添加到您的答案中?
    • @AliCAKIL 哎呀我的错。我更新了我的答案,需要添加名称来选择标签
    • @AliCAKIL 你能让它工作吗?
    • 是的,它奏效了。但是我添加了@for 循环来填充选择标签。否则显示为空。谢谢!我标记了它
    【解决方案2】:

    嗨,阿里,如果您只想拥有List&lt;int&gt;,您可以使用更简单的方法:

    1- 提供名称属性以供选择:

    <select name="BayiIdListesi" multiple>
    

    2- 之后,您应该重新安排您的操作,例如:

    public IActionResult BayiTopluEmailGonder(List<int> BayiIdListesi)
    

    或更好:

    public async Task<IActionResult> BayiTopluEmailGonder(List<int> BayiIdListesi)
    

    注意:棘手的部分是对 select 的 name 属性和操作参数 name 使用相同的值 (BayiIdListesi)。

    祝你好运,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 2021-01-21
      相关资源
      最近更新 更多