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

问题描述 投票:1回答:1

我有一个大约有10个下拉菜单的视图,当我将这个页面加载到没有保存数据的ID时,下拉菜单中选择的值为“请选择”,即创建新记录。

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

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

ModelState.Clear();

在调用load方法之前,但是问题仍然存在,有没有人遇到过这种情况?我已经google了一个解决方案,但唯一出现的是“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));
        }
}

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

c# asp.net-mvc asp.net-mvc-5
1个回答
0
投票

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

上面的最佳答案来自@StephenMuecke,因为他关于存储集合而不是SelectList的建议是正确的。

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

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

修理:

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

美好的一天,先生们。

© www.soinside.com 2019 - 2024. All rights reserved.