1

我有一段简单的代码尝试填充 3 个国家/地区的列表并默认选择第二项。出于某种原因,@Html.DropDownList 没有初始化屏幕中的第二个项目。有人可以指出这段代码有什么问题吗?

public class DemoController : Controller
{
    [HttpGet]
    public ActionResult Test()
    {
        List<SelectListItem> ddlCountries = new List<SelectListItem>();
        SelectListItem item1 = new SelectListItem { Selected = false, Text = "USA", Value = "1" };
        SelectListItem item2 = new SelectListItem { Selected = true, Text = "Ireland", Value = "2" };
        SelectListItem item3 = new SelectListItem { Selected = false, Text = "UK", Value = "3" };

        ddlCountries.Add(item1);
        ddlCountries.Add(item2);
        ddlCountries.Add(item3);

        ViewBag.ddlCountries = ddlCountries;
        return View();
    }

    [HttpPost]
    public string Test(string ddlCountries)
    {
        return "The selected Value was " + ddlCountries;
    }
}

下面是屏幕上的输出..

屏幕输出

quickwatch 窗口显示“Selected”属性已正确设置为值“2”,但屏幕并未反映这一点。

快速观察输出

视图代码如下

@{
    ViewBag.Title = "Test";
}

<h2>Test</h2>

@using (Html.BeginForm("Test", "Demo", FormMethod.Post))
{ 

@Html.DropDownList("ddlCountries", (IEnumerable<SelectListItem>) ViewBag.ddlCountries)
    <br />
    <input type="submit" value="submit" />
}
4

1 回答 1

6

尝试使用视图模型,它更容易、更安全、更干净:

public class MyViewModel
{
    public string SelectedCountryId { get; set; }
    public IEnumerable<SelectListItem> Countries { get; set; }
}

然后在你的控制器中:

public class DemoController : Controller
{
    [HttpGet]
    public ActionResult Test()
    {
        List<SelectListItem> ddlCountries = new List<SelectListItem>();
        SelectListItem item1 = new SelectListItem { Text = "USA", Value = "1" };
        SelectListItem item2 = new SelectListItem { Text = "Ireland", Value = "2" };
        SelectListItem item3 = new SelectListItem { Text = "UK", Value = "3" };

        ddlCountries.Add(item1);
        ddlCountries.Add(item2);
        ddlCountries.Add(item3);

        var model = new MyViewModel();
        model.Countries = ddlCountries;
        model.SelectedCountryId = "2"; // preseleted Ireland

        return View(model);
    }

    [HttpPost]
    public ActionResult Test(MyViewModel model)
    {
        return Content("The selected Value was " + model.SelectedCountryId);
    }
}

最后在您的强类型视图中:

@model MyViewModel
@{
    ViewBag.Title = "Test";
}

<h2>Test</h2>

@using (Html.BeginForm("Test", "Demo", FormMethod.Post))
{ 
    @Html.DropDownListFor(x => x.SelectedCountryId, Model.Countries)
    <br />
    <input type="submit" value="submit" />
}

这几乎是正确的方法。忘记任何 ViewBag 的东西。只需使用视图模型。视图的唯一信息源必须是视图模型。

顺便说一句,GET 控制器操作可以简化为:

[HttpGet]
public ActionResult Test()
{
    var model = new MyViewModel();
    model.Countries = new[]
    {
        new SelectListItem { Text = "USA", Value = "1" },
        new SelectListItem { Text = "Ireland", Value = "2" },
        new SelectListItem { Text = "UK", Value = "3" },
    };
    model.SelectedCountryId = "2"; // preseleted Ireland

    return View(model);
}

或者这些国家可以直接绑定在您的视图模型中:

public class MyViewModel
{
    public string SelectedCountryId { get; set; }
    public IEnumerable<SelectListItem> Countries 
    {
        get
        {
            return new[]
            {
                new SelectListItem { Text = "USA", Value = "1" },
                new SelectListItem { Text = "Ireland", Value = "2" },
                new SelectListItem { Text = "UK", Value = "3" },
            };
        }
    }
}

然后你的控制器变得更苗条:

public class DemoController : Controller
{
    [HttpGet]
    public ActionResult Test()
    {
        var model = new MyViewModel();
        model.SelectedCountryId = "2"; // preseleted Ireland
        return View(model);
    }

    [HttpPost]
    public ActionResult Test(MyViewModel model)
    {
        return Content("The selected Value was " + model.SelectedCountryId);
    }
}
于 2014-02-09T22:14:17.790 回答