首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET MVC DropDownList 與 DropDownListFor 完整用法大全:非強型別與強型別雙軌實戰

     編輯:ASP.NET 基礎

兩大 Helper 核心差異

特性@Html.DropDownList@Html.DropDownListFor
型別安全字串名稱(Magic String)Lambda 運算式(編譯期檢查)
Model 綁定手動對應 name 屬性自動綁定至 Model 屬性
驗證訊息需手動 @Html.ValidationMessage("name")自動 @Html.ValidationMessageFor(m => m.Prop)
適用場景簡單頁面、非強型別 View、動態表單標準強型別 View、表單編輯、資料註解驗證

一、非強型別:@Html.DropDownList

Controller

public ActionResult Index()
{
    // 方式 1:IEnumerable
    ViewBag.AreaId = _repo.GetAreas()
        .Select(a => new SelectListItem { Text = a.AreaName, Value = a.AreaId.ToString() });

    // 方式 2:SelectList(更簡潔)
    // ViewBag.AreaId = new SelectList(_repo.GetAreas(), "AreaId", "AreaName");

    return View();
}

View

@* 基本用法 *@
@Html.DropDownList("AreaId")

@* 加入預設提示項 *@
@Html.DropDownList("AreaId", "== 請選擇縣市 ==")

@* 自訂 HTML 屬性 *@
@Html.DropDownList("AreaId", null, "== 請選擇 ==", new { @class = "form-control", id = "ddlArea" })

二、強型別:@Html.DropDownListFor

ViewModel 設計(推薦將下拉資料來源放入 ViewModel)

public class SettingsViewModel
{
    // 表單繫結目標屬性
    public string SelectedAreaId { get; set; }

    // 下拉選單資料來源(唯讀)
    public IEnumerable AreaOptions { get; set; }
}

Controller

public ActionResult Index()
{
    var vm = new SettingsViewModel
    {
        AreaOptions = _repo.GetAreas()
            .Select(a => new SelectListItem { Text = a.AreaName, Value = a.AreaId.ToString() })
    };
    return View(vm);
}

[HttpPost]
public ActionResult Index(SettingsViewModel vm)
{
    if (!ModelState.IsValid)
    {
        // 重新填充下拉資料(必要!)
        vm.AreaOptions = _repo.GetAreas().Select(a => new SelectListItem { Text = a.AreaName, Value = a.AreaId.ToString() });
        return View(vm);
    }
    // 處理業務邏輯
    return RedirectToAction("Success");
}

View

@model SettingsViewModel

@* 兩參數重載:expression + IEnumerable *@
@Html.DropDownListFor(m => m.SelectedAreaId, Model.AreaOptions, "== 請選擇 ==", new { @class = "form-select" })

@* 驗證訊息自動對應 *@
@Html.ValidationMessageFor(m => m.SelectedAreaId, "", new { @class = "text-danger" })

三、進階實戰技巧

1. Enum 直接綁定下拉框

public enum OrderStatus { Pending = 1, Paid = 2, Shipped = 3, Completed = 4 }

public static class EnumExtensions
{
    public static IEnumerable ToSelectList(this TEnum enumObj, string selectedValue = null) where TEnum : struct
    {
        return Enum.GetValues(typeof(TEnum))
            .Cast()
            .Select(e => new SelectListItem
            {
                Text = e.GetDisplayName(), // 需自行實作或用 DescriptionAttribute
                Value = Convert.ToInt32(e).ToString(),
                Selected = e.ToString() == selectedValue
            });
    }
}

// View
@Html.DropDownListFor(m => m.Status, Model.Status.ToSelectList(Model.Status.ToString()))

2. 級聯下拉框

// View
@Html.DropDownListFor(m => m.ProvinceId, Model.Provinces, "請選擇省份", new { @class = "form-select", id = "ddlProvince" })
@Html.DropDownListFor(m => m.CityId, Enumerable.Empty(), "請先選擇省份", new { @class = "form-select", id = "ddlCity", disabled = "disabled" })

@section Scripts {
    
}

3. 選項分組

// Controller
var groups = new List
{
    new SelectListGroup { Name = "北部" },
    new SelectListGroup { Name = "中部" },
    new SelectListGroup { Name = "南部" }
};

ViewBag.Areas = _repo.GetAreas()
    .Select(a => new SelectListItem
    {
        Text = a.Name,
        Value = a.Id.ToString(),
        Group = groups.First(g => g.Name == a.Region)
    });

// View 會自動渲染 ...

四、常見問題速查表

問題原因解決
下拉框無資料ViewBag 鍵名拼寫錯誤、或未轉型 (IEnumerable)ViewBag.Key檢查鍵名一致性;強型別 ViewModel 避免此類錯誤
驗證失敗回傳 View 時下拉框空白POST Action 未重新填充 ViewModel 的集合屬性抽取 PopulateViewModel(vm) 方法,GET/POST 共用
Model 屬性有值但下拉框未選中集合中 Value 型別不匹配(如 int vs string)確保 Value 為字串,且與 Model 屬性 ToString() 一致
多選綁定失敗使用 DropDownListFor 而非 ListBoxForModel 屬性為陣列/清單時改用 @Html.ListBoxFor

五、最佳實踐總結

  1. 預設使用強型別 DropDownListFor + ViewModel,享受編譯期檢查與自動驗證。
  2. 下拉資料來源集中管理:建立 IDropdownService 或靜態 DropdownHelper,避免 Controller 重複查詢邏輯。
  3. POST 回傳 View 前必重填集合屬性,或使用 ModelState 自動保留(需 HtmlHelper 版本支援)。
  4. 複雜 UI 需求(分組、停用、圖示、搜尋)改用 Select2 / Choices.js 等前端元件,後端僅提供 JSON API。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved