0

我有以下视图模型:

 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在控制器中发布到时,我的模型总是有一个空 StateSelect。

如何确保将 StateSelect 推送到我Edit的帖子,以便在出现验证错误时可以重新填充下拉列表?

4

3 回答 3

1

您需要将您的收藏放在里面,<form />以便通过请求将其发布到服务器。在这种情况下,您很可能必须使用隐藏输入“手动”构建标记,或者将标记放在隐藏块中以对用户隐藏它。

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

于 2012-11-12T19:24:50.030 回答
0

要将 StateSelect 发布到控制器,您必须将其元素写入具有特殊名称的隐藏字段(查看此操作方法)。但是您可以在发布后在控制器操作 Edit 中重新填充此 IEnumerable。这将是正确的决定。

于 2012-11-12T19:32:46.323 回答
0

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

  1. HTTP 被设计为无状态,如果您将表单开发为尽可能无状态,它可以很好地扩展
  2. 在这样的表单中添加状态信息意味着生成不必要的 HTML,这需要时间在服务器上构建,需要时间传输到客户端并需要时间在浏览器中呈现,总体上会对性能造成很大影响(尽管你可以反对它使用“请求压缩”之类的东西)
  3. 如果你有 jQuery 之类的东西在客户端运行,那么 DOM 解析就会变得低效,因为你的 DOM 有太多的 HTML

话虽如此,您可以在 cookie 中以隐藏变量的形式实现一些数据持久性,因为它的数据量很小,并用于跟踪您的用户如何结束您的表单,或者向导用户完成了多少等。

于 2012-11-12T19:41:53.497 回答