如何在帖子中保持IEnumerable值

时间:2012-11-12 19:10:09

标签: c# asp.net-mvc

我有以下ViewModel:

 public class ViewModel
    {
        public Address Address {get;set;}
        [DisplayName("State")]
        public IEnumerable<SelectListItem> StateSelect { get; set; }
        public string StateID { get; set; }


        public ViewModel()
        {
        }

        public ViewModel(Stuff s, IDataContext dc)
        {
            StateSelect = dc.States.ToList().Select(x => new SelectListItem
                                                             {
                                                                 Value = x.Id.ToString(),
                                                                 Text = x.Name
                                                             });
           Address = s.Address;


        }

在我的编辑视图中:

<div class="display-field">
                @Html.DropDownListFor(model => model.Address.StateID, Model.StateSelect,)
                @Html.ValidationMessageFor(model => model.StateSelect)
            </div>

我的控制器:

public ActionResult Edit(int id)
        {
            var stuff = context.Stuff.Find(id);
            if (stuff== null)
            {
                throw new Exception("Stuff not found.");
            }
            return View(new ViewModel(stuff, context));
        }

        [HttpPost]
        public ActionResult Edit(ViewModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    //deeper logic, adds to ModelState.AddModelError
                    if(stillNotValid)
                         return View(model)
                }
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

现在,在我的Edit视图中,下拉列表正确填充。但是,当我在控制器中发布到Edit时,我的模型总是有一个null StateSelect。

如何确保将StateSelect推送到我的Edit帖子,这样如果有验证错误,我可以重新填充下拉列表?

3 个答案:

答案 0 :(得分:1)

您需要将集合放在<form />内,并将其发送到服务器并提出请求。在这种情况下,最有可能的是,您必须使用隐藏的输入“手动”构建标记,或者将您的标记放在隐藏的块中以将其隐藏起来。

您确定要来回发送此列表只是为了在视图模型中包含此集合吗?还有另一种解决方案 - 将此列表发送到ViewBag中的View并将其绑定到Actions中。这将使您免于<form />建模并减少帖子请求大小。

答案 1 :(得分:0)

要将StateSelect发布到控制器,必须将其元素写入具有特殊名称(look at this how to do it)的隐藏字段。 但你可以在发布后的控制器动作编辑中重新填充这个IEnumerable。这将是正确的决定。

答案 2 :(得分:0)

出于各种原因,我会避免在浏览器请求中保留数据

  1. HTTP设计为无状态,如果您将表单开发为尽可能无状态,它可以很好地扩展
  2. 以这样的形式添加状态信息意味着生成不必要的HTML,这需要花费时间在服务器上构建,花费时间转移到客户端并花费时间在浏览器中呈现,总体上会对性能产生重大影响(尽管你可以使用诸如“请求压缩”之类的东西反对它。
  3. 如果你有jQuery喜欢在客户端运行的东西,那么DOM解析会变得低效,因为你的DOM有太多的HTML
  4. 话虽如此,您可以在Cookie中以隐藏变量的形式实现一定数量的数据持久性,因为它包含少量数据并用于跟踪用户在表单上的结束方式,或者向导用户已完成了多少等