当 ModelState 无效时保留下拉信息

Raf*_*lin 3 c# validation asp.net-mvc

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

我已经使用了那里提出的解决方案,它解决了我的问题。不管怎样,我想避免每次 ModelState 无效时都查询数据库,所以我采用了这种方法。我想知道它是否有效,或者现在是否有更好的方法来做到这一点,考虑到我现在使用的是 MVC 5,而不是 MVC2(这是问题中的 MVC 版本,也许他们添加了一些新的东西来解决这。

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

public class ViewModel
{
    [DisplayName("Project")]
    public int ProjectID { get; set; }
    public List<SelectListItem> Projects { get; set; }

    //Other fields
}
Run Code Online (Sandbox Code Playgroud)

现在我的 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);
}
Run Code Online (Sandbox Code Playgroud)

我的帖子会是这样的:

[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);
}
Run Code Online (Sandbox Code Playgroud)

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

多谢!

Shy*_*yju 6

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();   
}
Run Code Online (Sandbox Code Playgroud)

并且在视图中

@Html.DropDownListFor(s=>s.ProjectID,Model.Projects)
Run Code Online (Sandbox Code Playgroud)

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

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

如果您太担心性能,您可以缓存Projects,这样就不需要每次都访问数据库。