C# 在Post上的模型中持久化SelectList

C# 在Post上的模型中持久化SelectList,c#,asp.net-mvc,asp.net-mvc-4,razor,C#,Asp.net Mvc,Asp.net Mvc 4,Razor,在MVC4中: 我的模型中有以下属性用于下拉列表: public SelectList Subjects { get; set; } 我在页面加载时的Index()操作中设置Subjects属性并返回模型 下拉列表可以很好地填充SelectListItems @Html.DropDownListFor(x => x.Subject, new SelectList(Model.Subjects, "Text", "Text", "Other")) 当我提交表单时,模型中的Subjects

在MVC4中:

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

public SelectList Subjects { get; set; }
我在页面加载时的Index()操作中设置Subjects属性并返回模型

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

@Html.DropDownListFor(x => x.Subject, new SelectList(Model.Subjects, "Text", "Text", "Other"))

当我提交表单时,模型中的Subjects SelectList已更改为空。必须有一种简单的方法在HttpPost上保持这一点。我想我也想提交并发布这个SelectList,以及所有表单字段?我该怎么做呢?

浏览器只在表单元素上发回所选的值。此外,将可从数据存储中检索的值发回不是一个好主意。您必须像填充列表时一样,提取列表中的项目


此外,MVC不像.NET网页那样维护页面的状态,因为它没有视图状态。开发人员完全负责管理后台发布之间的页面状态,这是MVC设计模式的本质。

通常认为,在
post
操作之后,您会重新填充
SelectList
。只需在方法中提取它,并在
Get
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;
    }
}
public ActionResult Create()
{
var模型=新的SubjectModel();
PopulateSubjectList(模型);
返回视图(模型);
}
[HttpPost]
公共行动结果创建(主题模型)
{
if(ModelState.IsValid)
{
//保存项目。。
}
//出了点问题。
PopulateSubjectList(模型);
返回视图(模型);
}
私有void填充SubjectList(SubjectModel模型)
{
if(MemoryCache.Default.Contains(“主题列表”))
{
//缓存中已存在SubjectList,
model.Subjects=(List)MemoryCache.Default.Get(“SubjectList”);
}
其他的
{
//选择列表在缓存中尚不存在,请从数据存储中提取项目。
List selectList=_db.Subjects.ToList();
//将列表缓存在内存中15分钟。
MemoryCache.Default.Add(“SubjectList”,selectList,DateTime.Now.AddMinutes(15));
model.Subjects=selectList;
}
}
注意:
MemoryCache
使用
System.Runtime.Caching
命名空间。请参阅:


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

请确保在回发后渲染视图时,加载视图时传递模型值。post上的SelectList为空。我不想再次加载它。我希望它持续下去。谢谢你的建议。如果您能详细说明“您可以缓存SelectList中的项目,这样您就不必对数据存储进行两次查询。”我将不胜感激。如果没有,则没有大问题。@rossbarish您可以在控制器(或业务层)和数据访问层之间添加第二级缓存层。我添加了一个简单的例子。我强烈建议将缓存抽象到一个单独的层,但是您的控制器(或业务层)不应该知道缓存。