[英]How to use multi selection in ASP.NET MVC application?
已经两天了,我试图找出并学习如何在ASP.NET Core中构建多选下拉列表,该列表是从db上下文中获得的,结果在构造函数中得到了进一步使用,因此我决定提出此问题。 我在任何地方都找不到如何使用已发布表格中的数据的方法,因此也许您可以为我提供帮助。 我相信我在控制器的POST操作中犯了一些错误。 我不确定如何将发布的数据发送到控制器中。
我在一个简单的例子上尝试各种组合。 现在最好的是:
ViewModel.cs:
public class ProductViewModel
{
public List<SelectListItem> Products { get; set; }
public int[] ProductIDs { get; set; }
}
Index.cshtml:
<!DOCTYPE html>
<html>
<head>
<title>Aplikacja</title>
<meta charset="utf-8">
<link rel="stylesheet" href="~/dist/allstyles.css" />
</head>
<body>
<form asp-action="Index" method="post">
<input type="hidden" asp-for="Products" />
<div class="form-group">
<label asp-for="Products">Produkty</label>
<select asp-for="ProductIDs" class="form-control" asp-items="ViewBag.Lista"></select>
</div>
<div class="text-center">
<button class="btn btn-primary" type="submit">Save</button>
<a asp-action="Index" class="btn btn-secondary">Cancel</a>
</div>
</form>
//ViewBag tests from controller
@ViewBag.Message //test1, returns 0
@ViewBag.Message2 //test2, returns 0
</body>
</html>
Controller.cs
public class ProductController : Controller
{
private readonly ApplicationDbContext _context; //database context
public ProductController(ApplicationDbContext context)
{
_context = context; //context for controller
}
//GET
public ActionResult Index()
{
ProductViewModel productVM = new ProductViewModel(); //viewmodel instance
PopulateProducts(); //populating dropdown
return View(productVM); //returning viewmodel
}
//POST (I belive that here I have screwed something a lot, I do not understand everything what is going on in this action)
[HttpPost]
public ActionResult Index(ProductViewModel productVM)
{
PopulateProducts();
if (productVM.ProductIDs !=null)
{
List<SelectListItem> selectedItems = productVM.Products.Where(p => productVM.ProductIDs.Contains(int.Parse(p.Value))).ToList();
ViewBag.Message = selectedItems.Count.ToString(); //returns 0
ViewBag.Message2 = productVM.Products.Count.ToString();//returns 0
}
return View(productVM);
}
private void PopulateProducts() //method populating dropdown list
{
var techQuery = from t in _context.Products //getting products context from database
orderby t.Name //sorting by names
select t; //selecting item (??)
if (techQuery != null) //if db context var is not null...
{
ViewBag.Lista = techQuery.Select(n => new SelectListItem { Text = n.Name, Value = n.ProductID.ToString() }); //...creating viewbag that is used for populating dropdown list in view
}
}
}
对于selectedItems
,我认为您需要从ViewBag.Lista
而不是productVM.Products
检索。 从View
向Controller
发布Form
, ProductViewModel.Products
始终为null。
我建议您使用ViewBag.Lista
在下面尝试解决方法。
public ActionResult ProductSelect(ProductViewModel productVM)
{
PopulateProducts();
if (productVM.ProductIDs != null)
{
List<SelectListItem> selectedItems = ((IEnumerable<SelectListItem>)ViewBag.Lista)
.Where(p => productVM.ProductIDs.Contains(int.Parse(p.Value))).ToList();
ViewBag.Message = selectedItems.Count.ToString(); //returns 0
ViewBag.Message2 = ((IEnumerable<SelectListItem>)ViewBag.Lista).Count().ToString();//returns 0
}
return View(productVM);
}
解决方案非常简单,而且您快到了。 我将建议一些更改。 在ViewModel.cs中,最好通过构造函数填充list属性。 它避免了Null引用异常,并易于使用该对象。
public ProductViewModel()
{
Products=new List<SelectListItem>();
}
public List<SelectListItem> Products { get; set; }
public int[] ProductIDs { get; set; }
在controller.cs中,我将进行更改以返回PopulateProducts以返回SelectList列表,而不是填充视图包。 注意:请关闭数据库连接,因为最终将耗尽连接池。
public class ProductController : Controller
{
private readonly ApplicationDbContext _context; //database context
public ProductController(ApplicationDbContext context)
{
_context = context; //context for controller
}
//GET
public ActionResult Index()
{
ProductViewModel productVM = new ProductViewModel(); //viewmodel instance
productVM.Products=PopulateProducts(); //populating dropdown
return View(productVM); //returning viewmodel
}
//POST (I belive that here I have screwed something a lot, I do not understand everything what is going on in this action)
[HttpPost]
public ActionResult Index(ProductViewModel productVM)
{
productVM.Products= PopulateProducts();
if (productVM.ProductIDs != null)
{
List<SelectListItem> selectedItems = productVM.Products.Where(p => productVM.ProductIDs.Contains(int.Parse(p.Value))).ToList();
ViewBag.Message = selectedItems.Count.ToString(); //returns 0
ViewBag.Message2 = productVM.Products.Count.ToString();//returns 0
}
return View(productVM);
}
private List<SelectListItem> PopulateProducts() //method populating dropdown list
{
var techQuery = from t in _context.Products //getting products context from database
orderby t.Name //sorting by names
select t; //selecting item (??)
if (techQuery != null) //if db context var is not null...
{
return techQuery.Select(n => new SelectListItem { Text = n.Name, Value = n.ProductID.ToString() }).ToList(); //...creating viewbag that is used for populating dropdown list in view
}
return null;
}
}
最后,在index.cshtml中,您需要指定用于查看的模型,并在@ Model.Products中填充产品ID。
@model ProductViewModel
<form asp-action="Index">
<div class="form-group">
<label asp-for="Products">Products</label>
<select asp-for="ProductIDs" class="form-control" asp-items="@Model.Products"></select>
</div>
<div class="text-center">
<button class="btn btn-primary" type="submit">Save</button>
<a asp-action="Index" class="btn btn-secondary">Cancel</a>
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.