MVC下拉菜单会记住先前记录中的先前选定值 [英] MVC dropdown remembers previous selected value from previous record

查看:81
本文介绍了MVC下拉菜单会记住先前记录中的先前选定值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大约有10个下拉菜单的视图,当我将该页面加载到一个没有保存数据的ID时,该下拉菜单具有选定的"Please Select"值,该值是在创建新记录时创建的./p>

当我使用保存有数据的ID导航回到该视图时,每个下拉列表的选定值都由我传递给视图的数据设置,该数据又是正确的.

但是,如果我随后使用未保存任何数据的ID重新加载页面,则下拉列表的选定值将根据上一条记录进行设置!我已经一遍又一遍地调试了它,对于没有数据链接的ID,我可以看到它为每个下拉列表的选定值传入NULL.我假设这与ModelState有关?所以我在控制器的开头尝试了以下内容

  ModelState.Clear(); 

在调用load方法之前,但是问题仍然存在,有人遇到过这个问题吗?我已经在谷歌上寻找解决方案,但唯一出现的是"MVC Dropdown不能记住所选的值",这与我遇到的问题相反.

  • 更新*

我认为我已经找到了问题,我目前正在使用

然后我重新加载页面而不是调用数据库,而是检查高速缓存,如果存在,我从那里拉出(这就是问题所在),我刚刚注释掉了从高速缓存中拉出的内容,并且下拉列表有效不再记得以前的值,但是为什么呢?

我知道这是一个老问题,但是当我在自己的类似问题中偶然发现此问题时,这里没有具体答案,我认为会继续前进,并给出一个对我有用的答案,并解释其原因.

上面的最佳答案来自@StephenMuecke,因为他对可以存储集合而不是SelectList.

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

对于另一条记录,在下一页加载时会出现问题,如果该dropdownvalue为null,则我检索的缓存列表将保留最后保存的所选项目,并且由于新项目为null,因此不会被覆盖,因此当先前选择的值应为null并且不应选择任何内容时,将显示该值.

要解决:

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

长安先生.

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.

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.

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! 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. I'm assuming this is to do with the 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? 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.

  • 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:

 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.

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>. 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.

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.

To fix:

  1. Cache List<YourObjectName>, and on retrieval convert it to a List<SelectListItem>.
  2. Other options include cloning or deserializing/serializing the List<SelectListItems> from cache.
  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.

这篇关于MVC下拉菜单会记住先前记录中的先前选定值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆