MVC下拉列表记住先前记录中的先前选定值

时间:2015-03-11 07:17:03

标签: c# asp.net-mvc asp.net-mvc-5

我有一个大约有10个下拉列表的视图,当我将此页面加载到没有保存数据的ID时,下拉列表的选择值为"请选择"这是创建一个新的记录。

当我使用保存了数据的ID导航回此视图时,每个下拉列表的选定值由我传入视图的数据设置,这也是正确的。

但是,如果我重新加载具有没有保存数据的ID的页面,则下拉列表的选定值将从之前的记录中设置!我已经反复调试了这个并且对于没有数据链接的ID,我可以看到它为每个下拉列表的选定值传递NULL。我假设这与ModelState有关吗?所以我在控制器的开头尝试了以下内容

ModelState.Clear();

在调用load方法之前,但是问题仍然存在,有没有人遇到过这种情况?我已经用谷歌搜索了解决方案,但唯一出现的问题是" MVC Dropdown不记得所选的值"这与我的问题相反。

  • 更新*

我想我已经找到了这个问题,我目前正在使用how to cache objects in MVC所以当我从页面的db加载下拉列表时,我将它们存储在缓存中,如下所示:

 if (CacheExtension.IsIncache("ListType"))
        {
            model.ListType = CacheExtension.GetFromCache<List<SelectListItem>>("ListType");
            model.ListTime = CacheExtension.GetFromCache<List<SelectListItem>>("ListDuration");
            model.ListPostageOption = CacheExtension.GetFromCache<List<SelectListItem>>("ListPostage");
            model.ListPricingType = CacheExtension.GetFromCache<List<SelectListItem>>("ListPrice");
        }
        else
        {

const string queryMultiple = @"

                                     SELECT StatusId, StatusDescription from [Status].table1

                                     SELECT StatusId, StatusDescription from [Status].table2

                                     SELECT StatusId, StatusDescription from [Status].table3

                                     SELECT StatusId, StatusDescription from [Status].table4";

        using (var sqlCon = new SqlConnection(Con.ReturnDatabaseConnection()).QueryMultiple(queryMultiple))
        {
            var duration = sqlCon.Read().ToList();
            var type = sqlCon.Read().ToList();
            var options = sqlCon.Read().ToList();
            var pricing = sqlCon.Read().ToList();

            model.ListType = new List<SelectListItem>();
            model.ListTime = new List<SelectListItem>();
            model.ListPostageOption= new List<SelectListItem>();
            model.ListPricingType = new List<SelectListItem>();

            model.ListType .AddRange(
                type.Select(
                    item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));

            model.ListTime.AddRange(
                duration.Select(
                    item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));

            model.ListPostageOption.AddRange(
                options.Select(
                    item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));

            model.ListPricingType.AddRange(
                pricing.Select(
                    item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));

            // Cache everything
            CacheExtension.SaveTocache("ListType", model.ListAdvertType, new DateTime(1));
            CacheExtension.SaveTocache("ListDuration", model.ListDuration, new DateTime(1));
            CacheExtension.SaveTocache("ListPostage", model.ListPostageOption, new DateTime(1));
            CacheExtension.SaveTocache("ListPrice", model.ListPricingType, new DateTime(1));
        }
}

我重新加载页面而不是调用数据库我检查缓存,如果它存在我从那里拉(这就是问题所在)我刚刚注释掉从缓存中拉出来并且它可以工作下拉列表不再记得以前的价值但为什么?

1 个答案:

答案 0 :(得分:0)

我知道这是一个古老的问题,但由于在我自己的类似问题中偶然发现这个问题时,我没有具体的答案,我想我会继续为我提供答案,并解释为什么会这样。

  

上面的最佳答案来自@StephenMuecke,作为他的建议   存储集合而不是SelectList是现场。

原因是因为 具有任何形式的内存缓存,返回的缓存对象是指向缓存中对象的指针,因此对返回的缓存对象所做的任何更改实际上都会写入缓存< / EM> 即可。就我而言,我正在存储List<SelectListItem>。每个SelectListItem都有一个selected属性,当我在DropDownListFor(...)razor语句中使用List<SelectListItem>时,在我的cshml页面上,它会将选择的任何项目分配回缓存。

在下一页加载不同记录时会出现问题,如果该dropdownvalue为null,我检索到的缓存列表保留了最后保存的选定项,并且因为新项目为null,所以它没有被覆盖,因此它当它应该为空并且应该没有选择任何东西时,它将显示先前选择的值。

修复:

  1. 缓存List<YourObjectName>,并在检索时将其转换为 List<SelectListItem>
  2. 其他选项包括克隆或反序列化/序列化 来自缓存的List<SelectListItems>
  3. 最终选项是不使用内存缓存,使用进程外或 分布式缓存机制,因为这将有效地序列化和 反序列化对象。
  4. 好日子先生。