在ASP.NET Core MVC中select标签助手

我需要帮助ASP.NET Core中的select标签助手。

我有一个员工名单,我试图绑定到一个select标签助手。 我的员工在一个List<Employee> EmployeesList ,选定的值将进入EmployeeId属性。 我的视图模型如下所示:

 public class MyViewModel { public int EmployeeId { get; set; } public string Comments { get; set; } public List<Employee> EmployeesList {get; set; } } 

我的员工类如下所示:

 public class Employee { public int Id { get; set; } public string FullName { get; set; } } 

我的问题是如何告诉我的select标签助手使用Id作为值,同时在下拉列表中显示FullName

 <select asp-for="EmployeeId" asp-items="???" /> 

我会很感激这个帮助。 谢谢。

使用Select Tag帮助器在视图中呈现SELECT元素

在您的GET操作中,创build视图模型的对象,加载EmployeeList集合属性并将其发送到视图。

 public IActionResult Create() { var vm = new MyViewModel(); vm.EmployeesList = new List<Employee> { new Employee {Id = 1, FullName = "Shyju"}, new Employee {Id = 2, FullName = "Scot"} }; return View(vm); } 

在你的创build视图中,从EmployeeList属性创build一个新的SelectList对象,并将其作为asp-items属性的值传递。

 @model MyViewModel <form asp-controller="Home" asp-action="Create"> <select asp-for="EmployeeId" asp-items="@(new SelectList(Model.EmployeesList,"Id","FullName"))"> <option>Please select one</option> </select> <input type="submit"/> </form> 

而你的HttpPost action方法接受提交的表单数据。

 [HttpPost] public IActionResult Create(MyViewModel model) { // check model.EmployeeId // to do : Save and redirect } 

或者,如果您的视图模型有一个List<SelectListItem>作为您的下拉项目的属性。

 public class MyViewModel { public int EmployeeId { get; set; } public string Comments { get; set; } public List<SelectListItem> Employees { set; get; } } 

而在你的行动中,

 public IActionResult Create() { var vm = new MyViewModel(); vm.Employees = new List<SelectListItem> { new SelectListItem {Text = "Shyju", Value = "1"}, new SelectListItem {Text = "Sean", Value = "2"} }; return View(vm); } 

在视图中,您可以直接使用Employees属性来获取asp-items

 @model MyViewModel <form asp-controller="Home" asp-action="Create"> <label>Comments</label> <input type="text" asp-for="Comments"/> <label>Lucky Employee</label> <select asp-for="EmployeeId" asp-items="@Model.Employees" > <option>Please select one</option> </select> <input type="submit"/> </form> 

SelectListItem类属于Microsoft.AspNet.Mvc.Rendering命名空间。

使用SelectList

有些人更喜欢使用SelectList类来保存呈现选项所需的项目。

 public class MyViewModel { public int EmployeeId { get; set; } public SelectList Employees { set; get; } } 

现在在您的GET操作中,您可以使用SelectList构造函数来填充视图模型的Employees属性。 确保你指定了dataValueFielddataTextField参数。

 public IActionResult Create() { var vm = new MyViewModel(); vm.Employees = new SelectList(GetEmployees(),"Id","FirstName"); return View(vm); } public IEnumerable<Employee> GetEmployees() { return new List<Employee> { new Employee { Id=1, FirstName="Shyju"}, new Employee { Id=2, FirstName="Bryan"} }; } 

在这里,我调用GetEmployees方法来获取Employee对象的列表,每个对象都有一个IdFirstName属性,我使用这些属性作为我们创build的SelectList对象的DataValueFieldDataTextField 。 您可以将硬编码列表更改为从数据库表中读取数据的代码。

视图代码将是相同的。

  <select asp-for="EmployeeId" asp-items="@Model.Employees" > <option>Please select one</option> </select> 

从一个string列表中呈现一个SELECT元素。

有时你可能想要从一个string列表中呈现一个select元素。 在这种情况下,您可以使用仅使用IEnumerable<T>SelectList构造函数

 var vm = new MyViewModel(); var items = new List<string> {"Monday", "Tuesday", "Wednesday"}; vm.Employees = new SelectList(items); return View(vm); 

视图代码将是相同的。

设置选定的选项

有时候,您可能希望在SELECT元素中设置一个选项作为默认选项(例如,在编辑屏幕中,您要加载之前保存的选项值)。 为此,您可以简单地将EmployeeId属性值设置为您想要select的选项的值。

 public IActionResult Create() { var vm = new MyViewModel(); vm.Employees = new List<SelectListItem> { new SelectListItem {Text = "Shyju", Value = "11"}, new SelectListItem {Text = "Tom", Value = "12"}, new SelectListItem {Text = "Jerry", Value = "13"} }; vm.EmployeeId =12; // Here you set the value return View(vm); } 

这将在页面呈现时在select元素中selectTom选项。

多select下拉菜单

如果你想渲染一个多select下拉列表,你可以简单地将你在视图中用于asp-for属性的视图模型属性改为数组types。

 public class MyViewModel { public int[] EmployeeIds { get; set; } public List<SelectListItem> Employees { set; get; } } 

这将为具有multiple属性的select元素呈现HTML标记,这将允许用户select多个选项。

 @model MyViewModel <select id="EmployeeIds" multiple="multiple" name="EmployeeIds"> <option>Please select one</option> <option value="1">Shyju</option> <option value="2">Sean</option> </select> 

在多选中设置select的选项

与单选相似,将EmployeeIds属性值设置为所需值的数组。

 public IActionResult Create() { var vm = new MyViewModel(); vm.Employees = new List<SelectListItem> { new SelectListItem {Text = "Shyju", Value = "11"}, new SelectListItem {Text = "Tom", Value = "12"}, new SelectListItem {Text = "Jerry", Value = "13"} }; vm.EmployeeIds= new int[] { 12,13} ; return View(vm); } 

这将在页面呈现时在多选元素中selectTom和Jerry选项。

使用ViewBag传输项目列表

如果你不想保留一个集合types的属性来传递选项列表到视图,你可以使用dynamic的ViewBag来做到这一点这不是我个人推荐的方法,因为viewbag是dynamic的,你的代码很容易被忽略错字错误

 public IActionResult Create() { ViewBag.Employees = new List<SelectListItem> { new SelectListItem {Text = "Shyju", Value = "1"}, new SelectListItem {Text = "Sean", Value = "2"} }; return View(new MyViewModel()); } 

并在视图中

 <select asp-for="EmployeeId" asp-items="@ViewBag.Employees"> <option>Please select one</option> </select> 

我为此创build了一个接口和一个<options>标签助手。 所以我没有必要每次必须填充<select>控件时将IEnumerable<T>项转换为IEnumerable<SelectListItem>

我认为它的作品非常漂亮

用法是这样的:

 <select asp-for="EmployeeId"> <option value="">Please select...</option> <options asp-items="@Model.EmployeesList" /> </select> 

为了使它与标签助手一起工作,你必须在你的类中实现这个接口:

 public class Employee : IIntegerListItem { public int Id { get; set; } public string FullName { get; set; } public int Value { return Id; } public string Text{ return FullName ; } } 

这些是所需的代码:

界面:

 public interface IIntegerListItem { int Value { get; } string Text { get; } } 

<options>标签助手:

 [HtmlTargetElement("options", Attributes = "asp-items")] public class OptionsTagHelper : TagHelper { public OptionsTagHelper(IHtmlGenerator generator) { Generator = generator; } [HtmlAttributeNotBound] public IHtmlGenerator Generator { get; set; } [HtmlAttributeName("asp-items")] public object Items { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.SuppressOutput(); // Is this <options /> element a child of a <select/> element the SelectTagHelper targeted? object formDataEntry; context.Items.TryGetValue(typeof(SelectTagHelper), out formDataEntry); var selectedValues = formDataEntry as ICollection<string>; var encodedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (selectedValues != null && selectedValues.Count != 0) { foreach (var selectedValue in selectedValues) { encodedValues.Add(Generator.Encode(selectedValue)); } } IEnumerable<SelectListItem> items = null; if (Items != null) { if (Items is IEnumerable) { var enumerable = Items as IEnumerable; if (Items is IEnumerable<SelectListItem>) items = Items as IEnumerable<SelectListItem>; else if (Items is IEnumerable<IIntegerListItem>) items = ((IEnumerable<IIntegerListItem>)Items).Select(x => new SelectListItem() { Selected = false, Value = ((IIntegerListItem)x).Value.ToString(), Text = ((IIntegerListItem)x).Text }); else throw new InvalidOperationException(string.Format("The {2} was unable to provide metadata about '{1}' expression value '{3}' for <options>.", "<options>", "ForAttributeName", nameof(IModelMetadataProvider), "For.Name")); } else { throw new InvalidOperationException("Invalid items for <options>"); } foreach (var item in items) { bool selected = (selectedValues != null && selectedValues.Contains(item.Value)) || encodedValues.Contains(item.Value); var selectedAttr = selected ? "selected='selected'" : ""; if (item.Value != null) output.Content.AppendHtml($"<option value='{item.Value}' {selectedAttr}>{item.Text}</option>"); else output.Content.AppendHtml($"<option>{item.Text}</option>"); } } } } 

可能有一些错字,但我认为目的很明确。 我不得不编辑一点点。

您也可以使用IHtmlHelper.GetEnumSelectList。

  // Summary: // Returns a select list for the given TEnum. // // Type parameters: // TEnum: // Type to generate a select list for. // // Returns: // An System.Collections.Generic.IEnumerable`1 containing the select list for the // given TEnum. // // Exceptions: // T:System.ArgumentException: // Thrown if TEnum is not an System.Enum or if it has a System.FlagsAttribute. IEnumerable<SelectListItem> GetEnumSelectList<TEnum>() where TEnum : struct; 

你可以使用下面的代码进行多选

 <select asp-for="EmployeeId" multiple="multiple" asp-items="@ViewBag.Employees"> <option>Please select</option> </select> 

你也可以使用:

 <select id="EmployeeId" name="EmployeeId" multiple="multiple" asp-items="@ViewBag.Employees"> <option>Please select</option> </select>