简体   繁体   English

MVC下拉菜单会记住先前记录中的先前选定值

[英]MVC dropdown remembers previous selected value from previous record

I have a view which has roughly 10 dropdowns, when I load this page against an ID which has no data saved against it the dropdowns have the selected value of "Please Select" which is create as im creating a new record. 我有一个大约有10个下拉列表的视图,当我针对没有任何数据保存的ID加载此页面时,下拉列表具有选定的“ Please Select”值,该值是在创建新记录时创建的。

When I navigate back to this view with an ID that has data saved against it, the selected values of each drop down is set by the data I pass in to the view which again is correct. 当我导航回带有保存有数据的ID的该视图时,每个下拉列表的选定值都由我传递给该视图的数据设置,这也是正确的。

But if I then reload the page with an ID that has no data saved against it, the selected values of the drop downs are set from the previous record! 但是,如果我随后使用未保存任何数据的ID重新加载页面,则从先前的记录中设置下拉菜单的选定值! I have debugged this over and over and for the ID that has no data linked it I can see its passing in NULL for the selected values for each drop downs. 我已经一遍又一遍地调试了它,对于没有数据链接的ID,我可以看到每个下拉列表的选定值都以NULL传递。 I'm assuming this is to do with the ModelState? 我假设这与ModelState有关? So I tried the following at the beginning of my controller 所以我在控制器的开头尝试了以下内容

ModelState.Clear();

Before the load method is called, but the issue still exists has anyone come across this? 在调用load方法之前,但是问题仍然存在,有人遇到过这个问题吗? I've googled for a solution but the only things that come up are "MVC Dropdown doesn't remember the selected value" which is the opposite to the issue I have. 我已经在谷歌上寻找解决方案,但唯一出现的是“ MVC Dropdown不能记住所选的值”,这与我遇到的问题相反。

  • Update * 更新*

I think I have found the issue, I'm currently using how to cache objects in MVC so when I load the dropdowns from the db for the page I then store them in the cache as follows: 我想我已经找到了问题,我目前正在使用如何在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));
        }
}

and I re-load the page instead of calling the database I check the cache, if it exists I pull from there (this is where the problem is) I have just commented out the pulling from the cache and it works the dropdowns no longer remember the previous values but why? 我重新加载页面而不是调用数据库,而是检查缓存,如果存在,则从那里拉出(这就是问题所在)。我刚刚注释掉了从缓存中拉出的内容,并且下拉列表不再起作用了以前的值,但是为什么呢?

I know this is an old question, but as there was no concrete answer here for me when I stumbled onto this question during my own similar issue, I thought I would go ahead and put an answer in that worked for me and explains why its happening. 我知道这是一个古老的问题,但是当我在自己的类似问题中偶然发现此问题时,这里没有针对我的具体答案,所以我认为我会继续提出一个对我有用的答案,并解释其原因。

The best answer above is from @StephenMuecke, as his suggestion about storing the collections instead of a SelectList is spot on. 上面最好的答案来自@StephenMuecke,因为他建议存储集合而不是SelectList。

The reason is because with any form of in-memory caching, the cached objects returned are pointers to the object in cache, so any change made to the returned cache object is actually written to the cache . 原因是因为在任何形式的内存中缓存中,返回的缓存对象都是指向缓存中对象的指针,因此对返回的缓存对象所做的任何更改实际上都会写入缓存中 In my case I was storing a List<SelectListItem> . 就我而言,我正在存储List<SelectListItem> Each SelectListItem has a selected attribute, and on my cshml pages when I used that List<SelectListItem> in a DropDownListFor(...) razor statement, it would assign whatever item was selected back into the cache. 每个SelectListItem都有一个selected属性,当我在DropDownListFor(...)剃刀语句中使用List<SelectListItem>时,在我的cshml页面上,它将选择的任何项目分配回缓存中。

The problem would arise on the next page load for a different record, if that dropdownvalue was null, the cached list I retrieved retained the last saved selected item, and because the new item was null, it was not overwritten, thus it would show the previously selected value when it should have been null and nothing should have been selected. 如果该dropdownvalue为null,则在下一个页面加载另一条记录时会出现问题,我检索的缓存列表保留了最后保存的所选项目,并且由于新项目为null,因此不会被覆盖,因此它将显示先前选择的值,当它应该为null且什么都没有选择时。

To fix: 修理:

  1. Cache List<YourObjectName> , and on retrieval convert it to a List<SelectListItem> . 缓存List<YourObjectName> ,并在检索时将其转换为List<SelectListItem>
  2. Other options include cloning or deserializing/serializing the List<SelectListItems> from cache. 其他选项包括从缓存克隆或反序列化/序列化List<SelectListItems>
  3. Final option is don't use in-memory cache, use an out of process or distributed cache mechanism, as this will effectively serialize and deserialize the object. 最后的选择是不使用内存中缓存,使用进程外或分布式缓存机制,因为这将有效地序列化和反序列化对象。

Good day sirs. 早上好先生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM