ModelState无效时保留下拉信息

我的DropDownLists存在一些问题,因为当我发布信息并且我的模型无效时,它会回到页面“空”,触发与此问题完全相同的错误。

我已经使用了那里提出的解决方案,它解决了我的问题。 无论如何,我想避免每当我的ModelState无效时查询数据库,我就采用这种方法。 我想知道它是否有效或者现在是否有更好的方法,考虑到我没有使用MVC来代替MVC2(这是MVC版本),我现在正在使用MVC 5,也许他们添加了一些新的东西来解决这个。

我所做的是在我的模型无效时使用TempData来保存信息。

public class ViewModel { [DisplayName("Project")] public int ProjectID { get; set; } public List Projects { get; set; } //Other fields } 

现在我的Create()动作(填充项目)

 [HttpGet] public ActionResult Create() { ViewModel vmodel = new ViewModel(); vmodel.Projects = db.GetProjects(User.Identity.Name).Select(x => new SelectListItem { Text = x.Description, Value = x.Id }).ToList(); TempData["Projects"] = vmodel.Projects; return View(vmodel); } 

我的post会是这样的:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(ViewModel vmodel) { //Clear TempData (in theory will clear my tempdata when read, so if this controller redirects to another action my tempdata will be clear) List projects = (TempData["Projects"] as List); if (ModelState.IsValid) { //... } //If it got here it's going back to the screen. //Repopulate the TempData (allowing it to exist one more trip) TempData["Projects"] = projects; vmodel.Projects = projects return View(atendimento); } 

这种做法是好的吗? 有没有更好的方法来实现这一点,而不是每次都查询数据库?

非常感谢!

您根本不需要使用TempData ,因为视图模型中有属性来保存下拉项。

 public ActionResult Create() { ViewModel vmodel = new ViewModel(); vmodel.Projects = GetProjects(); return View(vmodel); } private List GetProjects() { return db.GetProjects(User.Identity.Name) .Select(x => new SelectListItem { Text = x.Description, Value = x.Id }).ToList(); } 

在视图中

 @Html.DropDownListFor(s=>s.ProjectID,Model.Projects) 

在您的HttpPost操作中,如果ModelState无效,请再次重新加载Projects集合( 因为http是无状态的

 if(ModelState.IsValid) { // to do :Save and redirect } model.Projects = GetProjects(); return View(model); 

如果您过于担心性能,则可以缓存Projects以便每次都不需要访问数据库。

就个人而言,我不担心每次都要查询数据库进行此类操作。

如果添加/删除项目怎么办? 这可能是保存失败(选定项目已删除)的原因,用户永远不会意识到这一点。

我通常编写一个方法来填充我的所有视图模型的SelectListItem ,然后在我的Get和in Post使用它,如果validation失败的话。