DropDownListFor正在更改放置在缓存中的SelectedItem

时间:2019-04-29 12:34:30

标签: c# asp.net asp.net-mvc caching html.dropdownlistfor

我在asp.net MVC应用程序中的SelectListItems上使用缓存来存储我在许多页面上使用的SelectListItems。问题是,当我通过DropDownListFor使用它时,如果我向该DropDownListFor提供选定的值,则SelectListItems似乎将被更改...并且我想将SelectListItems保留在缓存中而没有“ selected”属性!

这是缓存:

public IEnumerable<SelectListItem> GetAllPersonnelCached()
{
CacheHelper.SaveToCache("mykey", valueToCache, 240); //HttpContext.Current.Cache.Add
CacheHelper.GetFromCache<IEnumerable<SelectListItem>>("mykey"); //HttpContext.Current.Cache["mykey"]
}

这是我正在使用的模型的属性

        public int? personnelSelected{ get; set; }
        public IEnumerable<SelectListItem> personnelList{ get; set; }

以及如何填充它:

responsibleSelected = 100;
personnelList = GetAllPersonnelCached();

这就是我在HTML部分使用数据的方式

@Html.DropDownListFor(x => x.personnelSelected, Model.personnelList, "PlaceHolder", new { data_placeholder = " " })

当我为网页运行此代码时,它运行良好。但是,当我调用GetAllPersonnelCached时,它给了我所有预期的项目,但是ID为100的ListItem是“ selecteditem”。为什么?我使用DropDownListFor的事实在List上进行了更改(由内存中的cache属性引用)?如果是,该如何预防?将选择列表项设为只读?

感谢所有人

1 个答案:

答案 0 :(得分:1)

DropDownListFor的{​​{3}}表明此扩展方法在内部设置了Selected属性。

因为SelectListItem是引用类型,所以此更改发生在缓存中的相应项目上。

防止这种情况的一种方法是从SelectListItem方法返回新的GetAllPersonnelCached对象,而不是原始的缓存对象。

public IEnumerable<SelectListItem> GetAllPersonnelCached()
{
    CacheHelper.SaveToCache("mykey", valueToCache, 240); 
    var cachedItems = CacheHelper.GetFromCache<IEnumerable<SelectListItem>>("mykey");

    return cachedItems.Select(o => new SelectListItem(o.Text, o.Value);
}  

您可能会考虑不缓存SelectListItem实例,而是将人员数据对象缓存起来,以便在检索时转换为SelectListItem实例。

// Assume your PersonnelData looks like below.    
class PersonnelData
{
    int Id { get; set; }
    string Name { get; set; }
}

public IEnumerable<SelectListItem> GetAllPersonnelCached()
{
    // valueToCache is a list of PersonnelData objects.
    CacheHelper.SaveToCache("mykey", valueToCache, 240);
    var cachedPersonnelData = CacheHelper.GetFromCache<IEnumerable<PersonnelData>>("mykey");

    return cachedPersonnelData.Select(o => new SelectListItem(o.Name, o.Id.ToString());
}