[ C# 開發隨筆 ] ASP.NET MVC 下拉選單預設值無法正常顯示問題排除

相信有些在寫 ASP.NET MVC 的時候,偶爾會遇到某一個欄位的下拉式選單無法正常帶出預設值,

以下為範例所使用下拉式選單的 Razor 語法 :

Html.DropDownListFor(model => model.Education, 
    (IEnumerable<SelectListItem>)ViewBag.EducationDDL, 
    new { @class = "form-control" })

此時當 model.Education 有值且符合 EducationDDL 內其中一個項目的 Value 時,此下拉選單應自動將該項目之 Selected 設為 True ,如以下範例:

Controller :

  public ActionResult Index()
  {
       ViewBag.EducationDDL = Education.EducationDropDownList;
       var member = new Member {Account = "A123456789", Education = "U0002"};

       return View(member);
  }

Education :

  public class Education
    {
        public static List<SelectListItem> EducationDropDownList =>
            new List<SelectListItem>()
            {
                new SelectListItem() {Text = "台北大學", Value = "U0001"},
                new SelectListItem() {Text = "台灣大學", Value = "U0002"},
                new SelectListItem() {Text = "東吳大學", Value = "U0003"},
                new SelectListItem() {Text = "輔仁大學", Value = "U0004"},
            };
    }

Member.cs

  public class Member
    {
        public string Account { get; set; }

        public string Education { get; set; }
    }

Index.cshtml:

@model Member

@{
    ViewData["Title"] = "Home Page";
}

<div class="row" style="margin-top: 5%">
    <div class="col-md-12">
        @using (Html.BeginForm())
        {

            <div class="form-group">
                @Html.DisplayNameFor(model => model.Account)
                @Html.TextBoxFor(model => model.Account, new { @class = "form-control" })
            </div>
            <div class="form-group">
                @Html.DisplayNameFor(model => model.Education)
                @Html.DropDownListFor(model => model.Education, (IEnumerable<SelectListItem>)ViewBag.EducationDDL,
                    new { @class = "form-control" })
            </div>
            <button type="submit" class="btn btn-primary">Register</button>
        }
    </div>
</div>

畫面:

以上是正常的情況,下拉選單有帶到我的預設值。

但是,如果我的 Controller 多了一行 ViewBag.Education = ""; 時,一切的美好都變調了。

修改的 Controller:

       public ActionResult Index()
        {
            // 多了這個 ViewBag 設定與使用下拉選單的欄位同名
            ViewBag.Education = "";
            ViewBag.EducationDDL = Education.EducationDropDownList;
            var member = new Member { Account = "A123456789", Education = "U0002" };

            return View(member);
        }

跑出來的結果就會變成第一個項目台北大學,沒有吃到該欄位的值,畫面如下:

由此可知,ViewBag 的參數名稱與使用下拉選單的欄位名稱相同時,會導致下拉選單預設值出錯,另外我有測試 ASP.Net Core 相同的程式語法,但卻沒有出現這個問題,因此判斷是.Net Framework 才會有問題。不過實際上為何會有這個問題,還需要請教大神們。

以上是下拉選單無法正常顯示指定值的問題可能,若你也遇到這個問題,就檢查看看你的 ViewBag 有沒有帶到與欄位同名的參數名稱。

同場加映:若 ActionResult 傳入的參數與該欄位同名,且有傳入參數(QueryString 有值 ) 時,也會造成這個問題(不區分大小寫)。如下:

       public ActionResult Index(string education)
        {
            // 多了這個 ViewBag 設定與使用下拉選單的欄位同名
            //ViewBag.Education = "";
            ViewBag.EducationDDL = Education.EducationDropDownList;
            var member = new Member { Account = "A123456789", Education = "U0002" };

            return View(member);
        }

這邊補上來自保哥給的建議-ViewBag.Education 會使下拉選單有問題的是因為他本來就不是這樣用的,

而是直接將 EducationDDL 改為 Education , 在 View 的部分則可直接用下列語法來做到下拉式選單。

Controller :

      public ActionResult Index()
        {
            ViewBag.Education = Education.EducationDropDownList;
            var member = new Member { Account = "A123456789", Education = "U0002" };

            return View(member);
        }

View:

 @Html.DropDownListFor(model => model.Education,null, new { @class = "form-control" })

在這邊感謝保哥的指導,又上到一課。

如有指正之處,歡迎隨時提出