如何从控制器中轻松创建DropDownList

时间:2011-06-20 18:45:16

标签: c# asp.net-mvc-3 razor

我有一个部分视图,其中包含一些看起来相同的<div>,而且每个public PartialViewResult GetMeals() { var meals = DataContext.GetMeals(); ViewBag.Units = new SelectList(DataContext.GetUnits,"Id","Name"); return PartialView("_Meals", meals); } @foreach (var m in Meals) { <div> @Html.DropDownList("Units", ViewBag.Units as List<SelectListItem>) <dig> 都包含一个DropdownList。现在,Dropdown列表中的选定值通常不同。初始值列表来自某些外部源。 所以那不行:

{{1}}

我当然可以为每个Meal创建另一个局部视图,但我不想进入部分视图层次结构并在另一个Partial 中创建Partial(尽管Leo DiCaprio会喜欢它)

你们能给我一个建议吗?

1 个答案:

答案 0 :(得分:2)

这就是我要做的。首先要摆脱ViewBag。然后定义一个视图模型:

public class MealViewModel
{
    public string MealDescription { get; set; }

    public string SelectedUnit { get; set; }
    public IEnumerable<SelectListItem> Units { get; set; }
}

在此视图模型中,您只需要放置视图(本例中为局部视图)所需的内容。

然后我会让我的控制器操作通过聚合来自任何地方的数据来填充此视图模型:

public ActionResult GetMeals()
{
    var meals = DataContext.GetMeals().ToList(); // <-- being eager with .ToList()
    var units = DataContext.GetUnits().ToList(); // <-- being eager with .ToList()
    var viewModel = meals.Select(meal => new MealViewModel
    {
        MealDescription = meal.Description,
        SelectedUnit = meal.UnitId,
        Units = units.Select(unit => new SelectListItem
        {
            Value = unit.Id.ToString(),
            Text = unit.Name
        })
    });
    return PartialView("_Meals", viewModel);
}

在部分_Meals内,我会使用编辑器模板:

@model IEnumerable<MealViewModel>
@Html.EditorForModel()

最后我会定义一个用餐的编辑器模板:(~/Views/Shared/EditorTemplates/MealViewModel.cshtml)将为模型的每个元素呈现:

@model MealViewModel
<h3>@Html.DisplayFor(x => x.MealDescription)</h3>
<div>    
    @Html.DropDownListFor(
        x => x.SelectedUnit,
        new SelectList(Model.Units)
    )
</div>

现在有更多循环,强制转换,错误命名的输入控件。您获得强类型,智能感知启用视图,美味: - )

现在,当您查看控制器操作时,必然会出现困扰您的内容:域模型和视图模型之间的重复映射代码。输入AutoMapper的世界,您将获得非常漂亮的代码。