如果ModelState无效,则在mvc post之间保留下拉列表

时间:2014-05-01 14:20:17

标签: c# asp.net-mvc persistence viewmodel

我有一个保存以下实体的简单表单

public class TravelInfo{
  public int ID {get;set;}
  public string CentreCode {get;set;}
  public DateTime TravelDate {get;set;}
}

我在我的控制器中有标准的2个创建方法 - 1个获得1个帖子并使用此视图模型将内容输入到视图中。

public class TravelInfoVM{
  public TravelInfo TravelInfo{get;set;}
  public IEnumerable<SelectListItem> Centres {get;set;}
}

控制器方法......

public ActionResult Create(){
  var CentresList = db.Centres.Select(c=> new SelectListItem {Text = c.Name, Value = c.Code}).ToList();
  TravelInfoVM = new TravelInfoVM(){Centres = CentresList};
  return View(TravelInfoVM);
}

[HttpPost]
public ActionResult Create(TravelInfoVM model){
  //the Centres part of the model at this point is empty
  if(ModelState.IsValid){
    //save
    //redirect
  }
  //do i **REALLY** have to get it again as below, or can I hold on to it somehow?
  model.Centres = db.Centres.Select(c=> new SelectListItem {Text = c.Name, Value = c.Code}).ToList();
  return View(model);
}

问题是,如果ModelState返回无效,我是否真的需要第二次往返数据库以获取中心列表?或者是否有更好/不同的方式在帖子中保留此列表,直到用户正确输入保存所需的详细信息..?或者我完全没有错误的结束......

1 个答案:

答案 0 :(得分:3)

并非没有将其添加到会话中,这是对会话的不恰当使用。否则,每个请求都是一个独特的雪花,即使它看起来是相同的,因为你返回相同的错误形式。

我不担心这个。它只是一个查询,并且由于它之前已发出相同的查询,因此很可能(或至少可以)缓存,因此无论如何它实际上可能无法访问数据库。

我建议的一件事是抽象查询,以便你的GET和POST操作只调用一个不会改变的函数,如果你需要改变选择列表的创建方式,你只是在一个地方做:

internal void PopulateCentreChoices(TravelInfoVM model)
{
    model.Centres = db.Centres.Select(c=> new SelectListItem {Text = c.Name, Value = c.Code}).ToList();
}

...

public ActionResult Create(){
  var model = new TravelInfoVM();
  PopulateCentreChoices(model);
  return View(model);
}

[HttpPost]
public ActionResult Create(TravelInfoVM model){
  if(ModelState.IsValid){
    //save
    //redirect
  }
  PopulateCentreChoices(model);
  return View(model);
}