You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 MVC:如何更简洁地从控制器填充DropDownList?

问题描述

我做了一个测试管理应用,设有测试编辑视图,顶部用DropDownList作为测试选择器,相关Razor代码如下:

@using TestMeAdmin.Models
@model TestMeAdmin.Models.TestViewModel

@Html.DropDownListFor(model => model.Tests, Model.Tests, "-- Select Test --", new { name = "ddlTests", id = "ddlTests" })

该下拉列表的数据来自控制器,当前控制器代码如下:

public async Task<IActionResult> Tests()
{

    var tests = await _repo.GetTestsAsync(filter: "");

    var viewModel = new TestViewModel()
    {
        TestId = "",
        Tests = new List<SelectListItem>()
    };

    foreach (var test in tests)
    {
        viewModel.Tests.Add(new SelectListItem { Value = test.TestId, Text = test.Test });
    }

    return View(viewModel);
}

目前功能正常,但我认为控制器里循环创建List<SelectListItem>的写法不够简洁,想知道有没有更优、更简洁的实现方式,不一定非要用Razor方案也可以。

优化方案

当然有更简洁的实现方式,核心是用LINQ的投影能力替代手动循环,以下是几种可行方案:

1. 用LINQ Select直接生成选项集合

直接通过LINQ的Select方法将测试数据转换为SelectListItem集合,一行代码完成转换,去掉冗余循环:

public async Task<IActionResult> Tests()
{
    var tests = await _repo.GetTestsAsync(filter: "");

    var viewModel = new TestViewModel()
    {
        TestId = "",
        Tests = tests.Select(test => new SelectListItem 
        { 
            Value = test.TestId, 
            Text = test.Test 
        }).ToList()
    };

    return View(viewModel);
}

这种写法和原逻辑完全一致,但代码更紧凑易读。

2. 封装复用方法(多场景使用时)

如果多个控制器或页面都需要生成测试的下拉列表,可以把转换逻辑封装成扩展方法,提升复用性:

public static class SelectListItemExtensions
{
    public static List<SelectListItem> ToTestSelectListItems(this IEnumerable<Test> tests)
    {
        return tests.Select(t => new SelectListItem 
        { 
            Value = t.TestId, 
            Text = t.Test 
        }).ToList();
    }
}

之后控制器代码可以进一步简化:

public async Task<IActionResult> Tests()
{
    var tests = await _repo.GetTestsAsync(filter: "");

    var viewModel = new TestViewModel()
    {
        TestId = "",
        Tests = tests.ToTestSelectListItems()
    };

    return View(viewModel);
}

3. 额外优化:修正Razor的DropDownListFor参数

注意你当前Razor代码里的DropDownListFor(model => model.Tests)存在参数错误——DropDownListFor的第一个参数应该绑定选中值的属性(比如model => model.SelectedTestId),而非下拉选项集合。正确写法如下:

@Html.DropDownListFor(model => model.SelectedTestId, Model.Tests, "-- Select Test --", new { id = "ddlTests" })

(无需手动指定name,DropDownListFor会自动根据绑定属性生成正确的name值)

内容的提问来源于stack exchange,提问作者Diego Perez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:02:41