1. ホーム
  2. c#

[解決済み】ASP.NET Core MVCのSelect Tag Helperについて

2022-04-12 09:13:50

質問

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 タグヘルパーを使用して 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);
}

そして、作成ビューで、新しい SelectList オブジェクトから EmployeeList プロパティの値として渡します。 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
}

または

ビューモデルに 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);
}

また、ビュー内では直接 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 名前空間を使用します。

select要素に明示的な閉じタグを使用していることを確認してください。自己完結型のタグを使用すると、タグヘルパーは空の SELECT 要素をレンダリングしてしまいます!

以下の方法 は機能しません

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

でも、これなら大丈夫。

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


エンティティフレームワークを使用してデータベースのテーブルからデータを取得する

上記の例では、オプションにハードコードされた項目を使用しています。そこで、多くの人が使っている Entity framework を使ってデータを取得するサンプルコードを追加してみようと思います。

DbContext オブジェクトのプロパティに Employees であり、その型は DbSet<Employee> ここで Employee エンティティクラスには IdName プロパティは次のようになります。

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 は、データベース・コンテキスト・オブジェクトです。ビューコードは上記と同じです。

セレクトリストの使用

を使用することを好む人もいます。 SelectList クラスを使用して、オプションのレンダリングに必要な項目を保持します。

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

これで、GET アクションの中で SelectList コンストラクタを使用して Employees プロパティを設定します。を指定していることを確認してください。 dataValueFielddataTextField というパラメータがあります。を使用することができます。 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 メソッドを使用して Employee オブジェクトのリストを取得し、それぞれに IdFirstName プロパティがあり、私はそれらのプロパティを DataValueFieldDataTextFieldSelectList オブジェクトを作成しました。ハードコードされたリストを、データベースのテーブルからデータを読み込むコードに変更することができます。

ビューコードは同じになります。

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

これにより、select 要素の HTML マークアップが multiple 属性は、ユーザーが複数の選択肢を選択できるようにするものです。

@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を使用してそれを行うことができます( これは、ビューバッグが動的であり、あなたのコードがキャッチされないタイポエラーになりやすいので、個人的に推奨されるアプローチではありません。 )

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>

項目のグループ化

select タグのヘルパーメソッドは、ドロップダウンの選択肢をグループ化することをサポートしています。必要なのは GroupSelectListItem をアクションメソッドに追加します。

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

ビューのコードに変更はありません。 オプトグループ の項目があります。