【问题标题】:Modifying List in ViewState does not persist在 ViewState 中修改列表不会持续存在
【发布时间】:2013-03-07 15:29:03
【问题描述】:

我有一个ViewState 持有一个List<T>

public List<AwesomeInt> MyList
{
  get { return ((List<int>)ViewState["MyIntList"]).Select(i => new AwesomeInt(i)).ToList(); }
  set { ViewState["MyIntList"] = value.GetIntegers(); }
}

现在,假设我打电话给MyList.Add(new AwesomeInt(3)),列表不会保留更改。

我相信这是因为 get 中的 .ToList() 正在创建一个新的 List 对象,因此永远不会调用 set,因此永远不会保存在 ViewState 中。

我之前已经解决过这个问题

  1. 不通过保存/调用直接调用.Select/.ToList() 转化。
  2. 不使用.Add.Remove 函数,而是使用 使用等号重新初始化 List

但是,如果类不可序列化并且我无法控制,则有时 1. 是不切实际的,而 2. 有点难看,因为我必须先将其复制到临时文件,然后添加,然后重新分配,或使用Concat 添加单个项目。

有更好的方法吗?

【问题讨论】:

  • 您是否有理由不能直接使用列表(例如return (List&lt;int&gt;)ViewState["MyIntList"];?我的意思是AwesomeInt 到底是什么,您为什么不存储它?它不是可序列化的吗?
  • 在某些情况下我无法控制它并且无法使其可序列化

标签: c# linq list viewstate


【解决方案1】:

好的,下面是一个功能齐全的控制台应用程序,它应该为您提供所需的功能。我利用了泛型,以便您可以构建任何必要类型的周边集合——但还要序列化一些更基本的东西。请记住,我在 set 中没有要写入的真实视图状态,但您可以修复它。

另外请记住,我在很短的时间内(例如 20 分钟)编写了这篇文章,因此可能存在优化(例如set ViewState 属性通常不是必需的,因为此解决方案修改了底层的基本数据源。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static List<int> _viewState = new List<int>();
        static RawCollection<AwesomeInt, int> ViewState
        {
            get { return new RawCollection<AwesomeInt, int>(_viewState); }
            set { _viewState = value.RawData; }
        }

        static void Main(string[] args)
        {
            ViewState.Add(new AwesomeInt(1));
            ViewState.Add(new AwesomeInt(2));
            WriteViewState();

            ViewState[0].Val = 5;
            WriteViewState();

            ViewState.RemoveAt(0);
            WriteViewState();

            for (int i = 10; i < 15; i++)
            {
                ViewState.Add(new AwesomeInt(i));
            }
            WriteViewState();
        }

        private static void WriteViewState()
        {
            for (int i = 0; i < ViewState.Count; i++)
            {
                Console.WriteLine("The value at index {0} is {1}.", i, ViewState[i].Val);
            }

            Console.WriteLine();
            Console.WriteLine();
        }
    }

    public class RawCollection<T, K> : Collection<T>
    {
        private List<K> _data;

        public RawCollection(List<K> data)
        {
            foreach (var i in data)
            {
                var o = (T)Activator.CreateInstance(typeof(T), i);
                var oI = o as IRawData<K>;
                oI.RawValueChanged += (sender) =>
                {
                    _data[this.IndexOf((T)sender)] = sender.Val;
                };

                this.Add(o);
            }
            _data = data;
        }

        public List<K> RawData
        {
            get
            {
                return new List<K>(
                    this.Items.Select(
                        i => ((IRawData<K>)i).Val));
            }
        }

        protected override void ClearItems()
        {
            base.ClearItems();

            if (_data == null) { return; }
            _data.Clear();
        }

        protected override void InsertItem(int index, T item)
        {
            base.InsertItem(index, item);

            if (_data == null) { return; }
            _data.Insert(index, ((IRawData<K>)item).Val);
        }

        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);

            if (_data == null) { return; }
            _data.RemoveAt(index);
        }

        protected override void SetItem(int index, T item)
        {
            base.SetItem(index, item);

            if (_data == null) { return; }
            _data[index] = ((IRawData<K>)item).Val;
        }
    }

    public class AwesomeInt : IRawData<int>
    {
        public AwesomeInt(int i)
        {
            _val = i;
        }

        private int _val;
        public int Val
        {
            get { return _val; }
            set
            {
                _val = value;
                OnRawValueChanged();
            }
        }

        public event Action<IRawData<int>> RawValueChanged;

        protected virtual void OnRawValueChanged()
        {
            if (RawValueChanged != null)
            {
                RawValueChanged(this);
            }
        }
    }

    public interface IRawData<T> : INotifyRawValueChanged<T>
    {
        T Val { get; set; }
    }

    public interface INotifyRawValueChanged<T>
    {
        event Action<IRawData<T>> RawValueChanged;
    }
}

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多