通过post传递IEnumerables的问题

时间:2011-06-16 15:43:40

标签: asp.net-mvc

重新发布我已经提出的更详细的问题:

我有两个ListBoxFors,其SelectList来自我的ViewModel中的2个IDictionary对象。页面最初加载(GET)时,它们按预期填充。但是当我发布时,它们的值被设置为null。为什么会这样?为什么没有传递IDictionary?

对于有问题的代码,功能的工作方式如下:彼此相邻有两个ListBox。用户可以单击一个框中的项目,然后使用按钮将其移动到另一个框中。因此,我不能只重新绑定ListBoxes,因为我想在POST上保留它们的内容。这是代码:

视图模型:

public int someValue { get; set; }
public IDictionary<int, string> currentCountries { get; set; }
public IDictionary<int, string> availableCountries { get; set; }

在我的编辑()动作中,我有以下内容:

IEnumerable<int, string> currentCountries = CountryRepository.GetCountries();
IEnumerable<int, string> availableCountries = CountryRepository.GetCountries();

var model = new ViewModel 
{
   currentCountries = currentCountries,
   availableCountries = availableCountries
}

在我的编辑(ViewModel模型)POST操作中,我有以下内容,现在没什么特别的:

return View(model);

我所讨论的部分的.cshtml看起来像是:

@Html.ListBoxFor(
   x => x.currentCountries
   new SelectList(Model.currentCountries, "key, "value")
)

@Html.ListBoxFor(
   x => x.availableCountries
   new SelectList(Model.currentCountries, "key", "value")
)

1 个答案:

答案 0 :(得分:0)

字典是模型绑定的PITA。我会避免它们并使用更标准的东西。还要记住,ListBox将所选id的列表发送到控制器动作,因此在这里使用字典是不合适的。

我会选择更像这样的视图模型:

public class MyViewModel
{
    public IEnumerable<int> AvailableCountriesIds { get; set; }
    public IEnumerable<SelectListItem> AvailableCountries { get; set; }

    public IEnumerable<int> CurrentCountriesIds { get; set; }
    public IEnumerable<SelectListItem> CurrentCountries { get; set; }
}

可以在控制器中填充:

public ActionResult Index()
{
    // Hardcoded the values in order to simplify but in your application
    // you would obviously be fetching those from your repository
    var currentCountries = new Dictionary<int, string> 
    { 
        { 1, "current country 1" },
        { 2, "current country 2" },
        { 3, "current country 3" },
    };
    var availableCountries = new Dictionary<int, string> 
    { 
        { 1, "available country 1" },
        { 2, "available country 2" },
    };

    var model = new MyViewModel
    {
        AvailableCountries = availableCountries.Select(x => new SelectListItem
        {
            Value = x.Key.ToString(),
            Text = x.Value
        }),

        CurrentCountries = currentCountries.Select(x => new SelectListItem
        {
            Value = x.Key.ToString(),
            Text = x.Value
        })
    };
    return View(model);
}

并在视图中:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.ListBoxFor(
        x => x.AvailableCountriesIds,
        new SelectList(Model.AvailableCountries , "Value", "Text")
    )

    @Html.ListBoxFor(
        x => x.CurrentCountriesIds,
        new SelectList(Model.CurrentCountries, "Value", "Text")
    )

    <input type="submit" value="OK" />
}

现在提交此表单时,它将正确绑定到以下操作:

[HttpPost]
public ActionResult Index(MyViewModel model)
{
    // model.AvailableCountriesIds and model.CurrentCountriesIds
    // will contain the ids of selected values in each of the two
    // listboxes
    ...
}

你可以download my test project说明这一点。