C# 在ASP.NET核心MVC中选择标记帮助器

C# 在ASP.NET核心MVC中选择标记帮助器,c#,asp.net-core,asp.net-core-mvc,tag-helpers,C#,Asp.net Core,Asp.net Core Mvc,Tag Helpers,我需要一些关于ASP.NET核心中选择标记帮助程序的帮助 我有一个试图绑定到select标记帮助器的员工列表。我的员工位于列表EmployeesList中,所选值将进入EmployeeId属性。我的视图模型如下所示: public class MyViewModel { public int EmployeeId { get; set; } public string Comments { get; set; } public List<Employee> Empl

我需要一些关于ASP.NET核心中选择标记帮助程序的帮助

我有一个试图绑定到select标记帮助器的员工列表。我的员工位于
列表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; }
}
我的问题是,在下拉列表中显示
FullName
时,如何告诉我的选择标记帮助器使用
Id
作为值

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


我很感激你能帮我。谢谢。

我为此创建了一个界面和一个
标记帮助程序。因此,每次填充
控件时,我不必将
IEnumerable
项转换为
IEnumerable

我认为它工作得很好

用法类似于:

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

以下是所需的代码:

界面:

public interface IIntegerListItem
{
    int Value { get; }
    string Text { get; }
}
标记帮助程序:

[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>");
            }
        }
    }
}
[HtmlTargetElement(“选项”,Attributes=“asp项目”)]
公共类选项TagHelper:TagHelper
{
公共选项StagHelper(IHTML生成器)
{
发电机=发电机;
}
[HTMLATTRIBUTTENOTBOND]
公共IHtmlGenerator生成器{get;set;}
[HtmlAttributeName(“asp项目”)]
公共对象项{get;set;}
公共覆盖无效进程(TagHelperContext上下文,TagHelperOutput输出)
{
output.SuppressOutput();
//此元素是SelectTagHelper目标元素的子元素吗?
对象formDataEntry;
context.Items.TryGetValue(typeof(SelectTagHelper),out-formDataEntry);
var selectedValues=formDataEntry作为ICollection;
var encodedValues=newhashset(StringComparer.OrdinalIgnoreCase);
if(selectedValues!=null&&selectedValues.Count!=0)
{
foreach(selectedValues中的var selectedValue)
{
encodedValues.Add(Generator.Encode(selectedValue));
}
}
IEnumerable items=null;
如果(项!=null)
{
如果(项是IEnumerable)
{
var enumerable=作为IEnumerable的项目;
如果(项是IEnumerable)
items=作为IEnumerable的项;
else if(项是IEnumerable)
items=((IEnumerable)items).Select(x=>newselectListItem(){Selected=false,Value=((IIntegerListItem)x).Value.ToString(),Text=((IIntegerListItem)x).Text});
其他的
抛出新的InvalidOperationException(string.Format)(“{2}无法为提供有关“{1}”表达式值“{3}”的元数据。”,
"",
“ForAttributeName”,
名称(IModelMetadataProvider),
"姓名);;
}
其他的
{
抛出新的InvalidOperationException(“的无效项”);
}
foreach(项目中的var项目)
{
bool selected=(selectedValues!=null&&selectedValues.Contains(item.Value))| | encodedValues.Contains(item.Value);
var selectedAttr=selected?“selected='selected'”:;
如果(item.Value!=null)
output.Content.AppendHtml($“{item.Text}”);
其他的
output.Content.AppendHtml($“{item.Text}”);
}
}
}
}
可能有一些拼写错误,但我认为目标是明确的。我必须编辑一点。

使用“选择标记”帮助程序渲染选择元素 在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);
}
和HttpPost操作方法来接受提交的表单数据

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

如果视图模型的下拉项属性为
列表

public class MyViewModel
{
    public int EmployeeId { get; set; }
    public string Comments { get; set; }
    public List<SelectListItem> Employees { set; get; }
}
SelectListItem
属于
Microsoft.AspNet.Mvc.Rendering
命名空间


确保为select元素使用显式结束标记。如果使用自动关闭标记方法,标记辅助对象将呈现一个空的SELECT元素

以下方法将不起作用

<select asp-for="EmployeeId" asp-items="@Model.Employees" />
您可以使用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
是数据库上下文对象。视图代码与上面相同

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

public class MyViewModel
{
    public int EmployeeId { get; set; }
    public SelectList Employees { set; get; }
}
@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>
现在,在GET操作中,可以使用
SelectList
构造函数填充视图模型的
Employees
属性。确保指定了
dataValueField
dataTextField
参数

public IActionResult Create()
{
    var vm = new MyViewModel();
    vm.Employees = new SelectList(GetEmployees(),"Id","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" }
    };
}
呈现字符串列表中的SELECT元素。 有时,您可能希望呈现字符串列表中的select元素。在这种情况下,您可以使用
SelectList
构造函数,它只接受
IEnumerable

这将在呈现页面时在select元素中选择Tom选项

多选下拉列表 如果要呈现多选下拉列表,只需将视图中用于
asp for
属性的视图模型属性更改为数组类型

public class MyViewModel
{
    public int[] EmployeeIds { get; set; }
    public List<SelectListItem> Employees { set; get; }
}
在“多选”中设置选定选项 与单选类似,将
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);
}

视图代码中没有更改。选择标记帮助器现在将呈现2个项目中的选项。

您也可以使用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;
//摘要:
//返回给定TEnum的选择列表。
//
//类型参数:
//十纳姆:
//键入以生成选择列表。
//
public class MyViewModel
{
    public int EmployeeId { get; set; }
    public SelectList Employees { set; get; }
}
public IActionResult Create()
{
    var vm = new MyViewModel();
    vm.Employees = new SelectList(GetEmployees(),"Id","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" }
    };
}
<select asp-for="EmployeeId" asp-items="@Model.Employees" >
    <option>Please select one</option>
</select>
var vm = new MyViewModel();
var items = new List<string> {"Monday", "Tuesday", "Wednesday"};
vm.Employees = new SelectList(items);
return View(vm);
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);
}
public class MyViewModel
{
    public int[] EmployeeIds { get; set; }
    public List<SelectListItem> Employees { set; get; }
}
@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>
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);
}
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>
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>
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);
}
    // 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>
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>
public enum Counter
{
    [Display(Name = "Number 1")]
    No1 = 1,
    [Display(Name = "Number 2")]
    No2 = 2,
    [Display(Name = "Number 3")]
    No3 = 3
}
public int No { get; set; }
<select asp-for="No" asp-items="@Html.GetEnumSelectList<Counter>()"></select>
<select id="No" name="No">
    <option value="1">Number 1</option>
    <option value="2">Number 2</option>
    <option value="3">Number 3</option>
</select>