我需要一些帮助与选择标签助手在ASP。净的核心。

我有一个员工列表,我试图将其绑定到一个选择标记帮助程序。我的员工在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; }
}

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

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

如果你能帮我,我会很感激的。谢谢。


当前回答

在得到:

public IActionResult Create()
{
    ViewData["Tags"] = new SelectList(_context.Tags, "Id", "Name");
    return View();
}

在文章:

var selectedIds= Request.Form["Tags"];

视图:

<label>Tags</label>
<select  asp-for="Tags"  id="Tags" name="Tags" class="form-control" asp-items="ViewBag.Tags" multiple></select>

其他回答

asp-items需要一些SelectListItem类的实例集合(来自命名空间Microsoft.AspNetCore.Mvc.Rendering),其中包含文本和值属性。因此,您可以将Employees集合转换为所需的方式。Select(e => new SelectListItem)FullName, e.Id.ToString())),并将结果放到asp-items属性中。

在得到:

public IActionResult Create()
{
    ViewData["Tags"] = new SelectList(_context.Tags, "Id", "Name");
    return View();
}

在文章:

var selectedIds= Request.Form["Tags"];

视图:

<label>Tags</label>
<select  asp-for="Tags"  id="Tags" name="Tags" class="form-control" asp-items="ViewBag.Tags" multiple></select>

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

<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>

你也可以使用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标签助手来呈现Select元素

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

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

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

@model MyViewModel
<form asp-controller="Home" asp-action="Create">

    <select asp-for="EmployeeId" 
            asp-items="@(new SelectList(Model.EmployeesList, nameof(Employee.Id), nameof(Employee.FullName)))">
        <option>Please select one</option>
    </select>

    <input type="submit"/>

</form>

和HttpPost操作方法来接受提交的表单数据。

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

Or

如果您的视图模型有List<SelectListItem>作为下拉项的属性。

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

在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);
}

在视图中,您可以直接为asp项目使用Employees属性。

@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命名空间。

确保为select元素使用了显式的结束标记。如果您使用自结束标记方法,标记助手将呈现一个空SELECT元素!

下面的方法行不通

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

但这是可行的。

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

使用实体框架从数据库表中获取数据

上面的例子为选项使用了硬编码项。所以我想我将添加一些示例代码来获取数据使用实体框架,因为很多人使用它。

让我们假设DbContext对象有一个名为Employees的属性,其类型为DbSet<Employee>,其中Employee实体类有一个Id和Name属性,如下所示

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

您可以使用LINQ查询来获取员工,并使用LINQ表达式中的Select方法为每个员工创建SelectListItem对象列表。

public IActionResult Create()
{
    var vm = new MyViewModel();
    vm.Employees = context.Employees
                          .Select(a => new SelectListItem() {  
                              Value = a.Id.ToString(),
                              Text = a.Name
                          })
                          .ToList();
    return View(vm);
}

假设context是你的db context对象。视图代码与上面相同。

使用SelectList

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

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

现在,在GET操作中,您可以使用SelectList构造函数填充视图模型的Employees属性。确保您指定了dataValueField和dataTextField参数。可以使用nameof表达式静态地链接字段名。

public IActionResult Create()
{
    var vm = new MyViewModel();
    vm.Employees = new SelectList(GetEmployees(), nameof(Employee.Id), nameof(Employee.FirstName));
    return View(vm);
}
public IEnumerable<Employee> GetEmployees()
{
    // hard coded list for demo. 
    // You may replace with real data from database to create Employee objects
    return new List<Employee>
    {
        new Employee { Id = 1, FirstName = "Shyju" },
        new Employee { Id = 2, FirstName = "Bryan" }
    };
}

在这里,我调用GetEmployees方法来获得员工对象的列表,每个都有一个Id和FirstName属性,我使用这些属性作为我们创建的SelectList对象的DataValueField和DataTextField。您可以将硬编码列表更改为从数据库表读取数据的代码。

视图代码将是相同的。

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

从字符串列表中呈现一个SELECT元素。

有时您可能想从字符串列表中呈现一个select元素。在这种情况下,您可以使用SelectList构造函数,它只接受IEnumerable<T>

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

视图代码将是相同的。

设置所选选项

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

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元素中的选项Tom。

多选择下拉菜单

如果你想呈现一个多选择下拉菜单,你可以简单地改变你的视图模型属性,你在你的视图中使用asp-for属性为数组类型。

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

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

@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>

在多选择中设置所选选项

类似于单一选择,将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);
}

这将在页面呈现时选择多选元素中的选项Tom and Jerry。

使用ViewBag传输项目列表

如果您不喜欢保留一个集合类型属性来将选项列表传递给视图,您可以使用动态ViewBag来这样做。(这不是我个人推荐的方法,因为viewbag是动态的,你的代码很容易出现未被发现的错别字错误)

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>

使用ViewBag传输项目列表和设置选定的选项

同上。您所要做的就是将属性(为其绑定下拉列表)值设置为您想要选择的选项的值。

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

    vm.EmployeeId = 2;  // This will set Bryan as selected

    return View(new MyViewModel());
}

在视图中

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

分组的

选择标记帮助器方法支持在下拉列表中对选项进行分组。您所要做的就是在操作方法中指定每个SelectListItem的Group属性值。

public IActionResult Create()
{
    var vm = new MyViewModel();
   
    var group1 = new SelectListGroup { Name = "Dev Team" };
    var group2 = new SelectListGroup { Name = "QA Team" };

    var employeeList = new List<SelectListItem>()
    {
        new SelectListItem() { Value = "1", Text = "Shyju", Group = group1 },
        new SelectListItem() { Value = "2", Text = "Bryan", Group = group1 },
        new SelectListItem() { Value = "3", Text = "Kevin", Group = group2 },
        new SelectListItem() { Value = "4", Text = "Alex", Group = group2 }
    };
    vm.Employees = employeeList;
    return View(vm);
}

视图代码没有变化。选择标记助手现在将呈现两个optgroup项中的选项。