モデル:User
public class User { public int UserId { get; set; } public string UserName { get; set; } [Column("Gender", TypeName = "int")] public Genders Gender { get; set; } public DateTime Birthday { get; set; } public string Email { get; set; } public string CompareEmail { get; set; } public string Tell { get; set; } }
列挙型:Genders
public enum Genders { Male = 1, Female }
Gendersって何やねんって感じですが、分かりやすくするため無理矢理複数形にしました。EntityFramework対応でモデルの方にColumn属性をつけてます。これでアプリ側ではGenders列挙型、データベース側ではint型で扱われるわけです。
ではモデルを元にコントローラーとビューを作ります。今回は0からではなく「EntityFrameworkを使用した…」テンプレートを使ってちゃっちゃっと作ってしまいましょう(この辺の課程は省略)。ウィザードによってIndexビューやEditビューができあがると思います。ここでやってみて分かったんですがモデルに列挙型を使っているとそのメンバだけテンプレートから弾かれちゃうみたいです。
実際のEditビューの実行結果
見ての通りGenderの項目がありません。まぁこれだけの話だったらHtmlヘルパーの「EditorFor()」とか使ってテキストボックスを自力で用意すればいい話なんですが、せっかく列挙型使ってんだからドロップダウンリストにしたらどうなのって思ってしまったわけです。
ここでやっと本題です。ドロップダウンリスト自体はHtmlヘルパーの「DropdownListFor()」で作れるんですが、どうやって列挙型の値をデータソースして渡すことができるのかってのが問題になってきます。ユーザー定義型つくってList化して渡すってのも出来なくもないですが、ちょっと回りくどいので今回は却下します。まぁ、長々書いても仕方ないので答えから書いちゃいますが以下をビューに追加します。
ビュー(Edit)に追加
<div class="editor-label"> @Html.LabelFor(model => model.Gender) </div> <div class="editor-field"> @Html.DropDownListFor(model => model.Gender, new SelectList(Enum.GetValues(Model.Gender.GetType()))) </div>
簡単に解説すると「Enumクラス」の「GetValues」メソッドで列挙型の値を取得し、リストを渡してます。
追加後の実行結果
ばっちり、列挙型でドロップダウンリストが出来ました。でもこれで調子に乗ってCreateビューも同じようにやってみると…。
Createビューの実行結果
NullだよNullってわけです。モデルがインスタンス化されてない模様です。これの原因はコントローラー側も見れば一目瞭然です。
Createメソッド
public ActionResult Create() { return View(); }
うーん、まさに何もしてないわけです。ここで頑張ってモデル側がNullでもどうにかしちゃう拡張ヘルパーを作ってもいいかもしれませんが、ここは手っ取り早くCreateメソッドの方に手を加えて解決にしちゃいます。
Createメソッドの修正
public ActionResult Create() { var model = new User(); return View(model); }
当たり前ですがこれでモデルはインスタンス化されビューに渡されます。一応、実行結果を貼っておきます。
修正後の実行結果
以上で、今回は終了です。列挙型についてはもっと応用が効きそうな気がしますが、まだまだ実力不足でアイデアが…。