ASP.NET Core - Selectlist実装パターンメモ

# タグヘルパーを使用する場合

### 基本形
<img width="643" alt="基本形.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403060/777800c5-a77f-35ef-451d-04d7bdf41e10.png">

<details><summary>サンプルコード</summary><div>

``` html:index.cshtml
@model SampleMVCApp.ViewModels.StationViewModel;

<div class="text-center">
    <h1 class="display-3">Index</h1>
    <form method="post" asp-controller="Station" asp-action="Index">
        <div class="form-group">
            <select asp-for="Station" asp-items="Model.StationsJY" class="form-control"></select>
        </div>
        <div class="form-group">
            <input type="submit" class="btn btn-primary" />
        </div>
    </form>
</div>
```

``` c#:StationViewModel.cs
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace SampleMVCApp.ViewModels
{
    public class StationViewModel
    {
        public string Station { get; set; }

        public List<SelectListItem> StationsJY { get; } = new List<SelectListItem>
        {
            new SelectListItem{Value = "JY01", Text = "東京"},
            new SelectListItem{Value = "JY13", Text = "池袋"},
            new SelectListItem{Value = "JY17", Text = "新宿"},
            new SelectListItem{Value = "JY20", Text = "渋谷"},
            new SelectListItem{Value = "JY25", Text = "品川"},
            new SelectListItem{Value = "JY29", Text = "有楽町"}
        };
    }
}
```

``` C#:StationController.cs
using Microsoft.AspNetCore.Mvc;
using SampleMVCApp.ViewModels;

namespace SampleMVCApp.Controllers
{
    public class StationController : Controller
    {
        public IActionResult Index()
        {
            var model = new StationViewModel();
            model.Station = "JY20";

            return View(model);
        }

        [HttpPost]
        public IActionResult Index(StationViewModel model)
        {
            return View(model);
        }
    }
}
```
</div></details>

---

### Enumを使用する
（表示上の見た目は基本形と同じ）
<img width="643" alt="基本形.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403060/777800c5-a77f-35ef-451d-04d7bdf41e10.png">

<details><summary>サンプルコード</summary><div>

``` html:index.cshtml
@model SampleMVCApp.ViewModels.StationEnumViewModel;

<div class="text-center">
    <h1 class="display-3">IndexEnum</h1>
    <form method="post" asp-controller="Station" asp-action="Index">
        <div class="form-group">
            <select asp-for="EnumStation" 
                    asp-items="Html.GetEnumSelectList<SampleMVCApp.ViewModels.StationEnumViewModel.StationEnum>()" 
                    class="form-control">
            </select>
        </div>
        <div class="form-group">
            <input type="submit" class="btn btn-primary" />
        </div>
    </form>
</div>
```

``` c#:StationViewModel.cs
using System.ComponentModel.DataAnnotations;

namespace SampleMVCApp.ViewModels
{
    public class StationEnumViewModel
    {
        public StationEnum EnumStation { get; set; }

        public enum StationEnum
        {
            [Display(Name = "東京")]
            JY01,
            [Display(Name = "池袋")]
            JY13,
            [Display(Name = "新宿")]
            JY17,
            [Display(Name = "渋谷")]
            JY20,
            [Display(Name = "品川")]
            JY25,
            [Display(Name = "有楽町")]
            JY29
        }
    }
}
```

``` C#:StationController.cs
using Microsoft.AspNetCore.Mvc;
using SampleMVCApp.ViewModels;
using static SampleMVCApp.ViewModels.StationEnumViewModel;

namespace SampleMVCApp.Controllers
{
    public class StationController : Controller
    {
        public IActionResult Index()
        {
            var model = new StationEnumViewModel();
            model.EnumStation = StationEnum.JY20;

            return View(model);
        }

        [HttpPost]
        public IActionResult Index(StationViewModel model)
        {
            return View(model);
        }
    }
}
```
</div></details>

---

### オプショングループを使用する
<img width="630" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403060/7c5e5e54-cb1b-696b-4851-12d75911cf4e.png">

<details><summary>サンプルコード</summary><div>

``` html:index.cshtml
@model SampleMVCApp.ViewModels.StationViewModelGroup

<div class="text-center">
    <h1 class="display-3">Index</h1>
    <form method="post" asp-controller="Station" asp-action="Index">
        <div class="form-group">
            <select asp-for="Station" asp-items="Model.Stations" class="form-control">
            </select>
        </div>
        <div class="form-group">
            <input type="submit" class="btn btn-primary" />
        </div>
    </form>
</div>
```

``` c#:StationViewModel.cs
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace SampleMVCApp.ViewModels
{
    public class StationViewModelGroup
    {
        public string Station { get; set; }

        public List<SelectListItem> Stations { get; }

        public StationViewModelGroup()
        {
            var YamanoteLineGroup = new SelectListGroup { Name = "山手線" };
            var ChuoLineGroup = new SelectListGroup { Name = "中央線" };

            Stations = new List<SelectListItem>
            {
                new SelectListItem
                {
                    Value = "JY01",
                    Text = "東京",
                    Group = YamanoteLineGroup
                },
                new SelectListItem
                {
                    Value = "JY13",
                    Text = "池袋",
                    Group = YamanoteLineGroup
                },
                new SelectListItem
                {
                    Value = "JY17",
                    Text = "新宿",
                    Group = YamanoteLineGroup
                },
                new SelectListItem
                {
                    Value = "JY20",
                    Text = "渋谷",
                    Group = YamanoteLineGroup
                },
                new SelectListItem
                {
                    Value = "JY25",
                    Text = "品川",
                    Group = YamanoteLineGroup
                },
                new SelectListItem
                {
                    Value = "JY29",
                    Text = "有楽町",
                    Group = YamanoteLineGroup
                },
                new SelectListItem
                {
                    Value = "JC01",
                    Text = "東京",
                    Group = ChuoLineGroup
                },
                new SelectListItem
                {
                    Value = "JC12",
                    Text = "三鷹",
                    Group = ChuoLineGroup
                },
                new SelectListItem
                {
                    Value = "JC24",
                    Text = "高尾",
                    Group = ChuoLineGroup
                },
            };
        }
    }

}
```

``` C#:StationController.cs
using Microsoft.AspNetCore.Mvc;
using SampleMVCApp.ViewModels;

namespace SampleMVCApp.Controllers
{
    public class StationController : Controller
    {
        public IActionResult Index()
        {
            var model = new StationViewModelGroup();
            model.Station = "JY20";

            return View(model);
        }

        [HttpPost]
        public IActionResult Index(StationViewModelGroup model)
        {
            return View(model);
        }
    }
}
```
</div></details>

---

### 複数選択できるようにする
<img width="642" alt="複数選択.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403060/9fb61fd9-b2e2-cde2-0007-1dae415f91a9.png">

<details><summary>サンプルコード</summary><div>

``` html:index.cshtml
@model SampleMVCApp.ViewModels.StationViewModelIEnumerable

<div class="text-center">
    <h1 class="display-3">Index</h1>
    <form method="post" asp-controller="Station" asp-action="Index">
        <div class="form-group">
            <select asp-for="Stations" asp-items="Model.StationsJY" class="form-control"></select>
        </div>
        <div class="form-group">
            <input type="submit" class="btn btn-primary" />
        </div>
    </form>
</div>
```

``` c#:StationViewModel.cs
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace SampleMVCApp.ViewModels
{
    public class StationViewModelIEnumerable
    {
        public IEnumerable<string> Stations { get; set; }

        public List<SelectListItem> StationsJY { get; } = new List<SelectListItem>
        {
            new SelectListItem{Value = "JY01", Text = "東京"},
            new SelectListItem{Value = "JY13", Text = "池袋"},
            new SelectListItem{Value = "JY17", Text = "新宿"},
            new SelectListItem{Value = "JY20", Text = "渋谷"},
            new SelectListItem{Value = "JY25", Text = "品川"},
            new SelectListItem{Value = "JY29", Text = "有楽町"}
        };
    }
}
```

``` C#:StationController.cs
using Microsoft.AspNetCore.Mvc;
using SampleMVCApp.ViewModels;

namespace SampleMVCApp.Controllers
{
    public class StationController : Controller
    {
        public IActionResult Index()
        {
            var model = new StationViewModelIEnumerable();
            model.Stations = new string[2] { "JY17", "JY25" };

            return View(model);
        }

        [HttpPost]
        public IActionResult Index(StationViewModelIEnumerable model)
        {
            return View(model);
        }
    }
}
```
</div></details>

# HTMLヘルパーを使用する場合
（追記予定）

# 参考
[Microsoft Docs ASP.NET Core > Webアプリ > 選択タグヘルパー](https://docs.microsoft.com/ja-jp/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1)
[『C#フレームワーク ASP.NET Core3入門』](https://www.amazon.co.jp/%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-ASP-NET-Core3%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/479806050X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=asp.net+core3&qid=1581755339&sr=8-1)

※コード中のSelectListのValue値は[駅ナンバリング（山手線）]((https://www.jreast.co.jp/press/2016/20160402.pdf))を参考