在Post上的模型中保留SelectList

Ros*_*ish 7 c# asp.net-mvc razor asp.net-mvc-4

在MVC4中:

我的模型中有以下属性用于下拉列表:

public SelectList Subjects { get; set; }
Run Code Online (Sandbox Code Playgroud)

我在页面加载的Index()Action中设置了Subjects属性并返回模型.

使用SelectListItems可以很好地填充下拉列表.

@Html.DropDownListFor(x => x.Subject, new SelectList(Model.Subjects, "Text", "Text", "Other"))
Run Code Online (Sandbox Code Playgroud)

当我提交表单时,模型中的Subjects SelectList已更改为null.必须有一种简单的方法来持久化HttpPost.我想我也想提交和发布这个SelectList,以及所有表单字段?我该怎么做?

Hen*_*ema 6

通常会接受您SelectListPost操作后重新填充a .只需在方法中提取它并在Getand Post动作中调用它.

将它再次发回控制器是不可取的.您可以在SelectList中缓存项目,这样您就不必对数据存储进行两次查询.

例:

public ActionResult Create()
{
    var model = new SubjectModel();
    PopulateSubjectList(model);
    return View(model);
}

[HttpPost]
public ActionResult Create(SubjectModel model)
{
    if (ModelState.IsValid)
    {
        // Save item..
    }
    // Something went wrong.
    PopulateSubjectList(model);
    return View(model);
}

private void PopulateSubjectList(SubjectModel model)
{
    if (MemoryCache.Default.Contains("SubjectList"))
    {
        // The SubjectList already exists in the cache,
        model.Subjects = (List<Subject>)MemoryCache.Default.Get("SubjectList");
    }
    else
    {
        // The select list does not yet exists in the cache, fetch items from the data store.
        List<Subject> selectList = _db.Subjects.ToList();

        // Cache the list in memory for 15 minutes.
        MemoryCache.Default.Add("SubjectList", selectList, DateTime.Now.AddMinutes(15));
        model.Subjects = selectList;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:MemoryCache使用System.Runtime.Caching命名空间.请参阅:System.Runtime.Caching命名空间.

此外,缓存应位于控制器(或业务层)与数据访问层之间的单独层中,这只是为了清晰起见.

  • @RossBarbish,您可以在控制器(或业务层)和数据访问层之间添加第二级缓存层。我添加了一个简单的例子。我强烈建议将缓存抽象到一个单独的层,但是您的控制器(或业务层)应该不了解缓存。 (2认同)