我的DropDownLists存在一些问题,因为当我发布信息并且我的模型无效时,它会回到页面“空”,触发与this question完全相同的错误。
我已经使用了那里提出的解决方案,它解决了我的问题。无论如何,我想避免每当我的ModelState无效时查询数据库,我就采用这种方法。我想知道它是否有效或者现在是否有更好的方法来实现它,考虑到我没有使用MVC来代替MVC2(这是question的MVC版本),也许他们添加了解决这个问题的新方法。
我所做的是在我的模型无效时使用TempData来保存信息。
public class ViewModel
{
[DisplayName("Project")]
public int ProjectID { get; set; }
public List<SelectListItem> 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);
}
我的帖子就是这样的:
[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<SelectListItem> projects = (TempData["Projects"] as List<SelectListItem>);
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);
}
这种做法是好的吗?有没有更好的方法来实现这一目标而不是每次都查询数据库?
非常感谢!
答案 0 :(得分:3)
您根本不需要使用TempData
,因为视图模型中有属性来保存下拉项。
public ActionResult Create()
{
ViewModel vmodel = new ViewModel();
vmodel.Projects = GetProjects();
return View(vmodel);
}
private List<SelectListItem> 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
,这样如果您对性能过于担心,则无需每次都访问数据库。
答案 1 :(得分:1)
就个人而言,我不担心每次都要查询数据库进行此类操作。
如果添加/删除项目怎么办?这可能是保存失败(选定的项目被删除)以及用户永远不会意识到的原因。
我通常会编写一个方法来填充我的所有视图模型的SelectListItem
,然后在我的Get
和Post
中使用此方法,如果验证失败。