1 namespace System.Web.Mvc {
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Diagnostics.CodeAnalysis;
7 using System.Runtime.Serialization;
9 public class TempDataDictionary : IDictionary<string, object> {
10 internal const string _tempDataSerializationKey = "__tempData";
12 private Dictionary<string, object> _data;
13 private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
14 private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
16 public TempDataDictionary() {
17 _data = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
26 public ICollection<string> Keys {
33 _retainedKeys.Clear();
34 _retainedKeys.UnionWith(_data.Keys);
37 public void Keep(string key) {
38 _retainedKeys.Add(key);
41 public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
42 IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);
43 _data = (providerDictionary != null) ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase) :
44 new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
45 _initialKeys = new HashSet<string>(_data.Keys, StringComparer.OrdinalIgnoreCase);
46 _retainedKeys.Clear();
49 public object Peek(string key) {
51 _data.TryGetValue(key, out value);
55 public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
56 string[] keysToKeep = _initialKeys.Union(_retainedKeys, StringComparer.OrdinalIgnoreCase).ToArray();
57 string[] keysToRemove = _data.Keys.Except(keysToKeep, StringComparer.OrdinalIgnoreCase).ToArray();
58 foreach (string key in keysToRemove) {
61 tempDataProvider.SaveTempData(controllerContext, _data);
64 public ICollection<object> Values {
70 public object this[string key] {
73 if (TryGetValue(key, out value)) {
74 _initialKeys.Remove(key);
81 _initialKeys.Add(key);
85 public void Add(string key, object value) {
86 _data.Add(key, value);
87 _initialKeys.Add(key);
92 _retainedKeys.Clear();
96 public bool ContainsKey(string key) {
97 return _data.ContainsKey(key);
100 public bool ContainsValue(object value) {
101 return _data.ContainsValue(value);
104 public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
105 return new TempDataDictionaryEnumerator(this);
108 public bool Remove(string key) {
109 _retainedKeys.Remove(key);
110 _initialKeys.Remove(key);
111 return _data.Remove(key);
114 public bool TryGetValue(string key, out object value) {
115 _initialKeys.Remove(key);
116 return _data.TryGetValue(key, out value);
119 #region ICollection<KeyValuePair<string, object>> Implementation
120 bool ICollection<KeyValuePair<string, object>>.IsReadOnly {
122 return ((ICollection<KeyValuePair<string, object>>)_data).IsReadOnly;
126 void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int index) {
127 ((ICollection<KeyValuePair<string, object>>)_data).CopyTo(array, index);
130 void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> keyValuePair) {
131 _initialKeys.Add(keyValuePair.Key);
132 ((ICollection<KeyValuePair<string, object>>)_data).Add(keyValuePair);
135 bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> keyValuePair) {
136 return ((ICollection<KeyValuePair<string, object>>)_data).Contains(keyValuePair);
139 bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> keyValuePair) {
140 _initialKeys.Remove(keyValuePair.Key);
141 return ((ICollection<KeyValuePair<string, object>>)_data).Remove(keyValuePair);
145 #region IEnumerable Implementation
146 IEnumerator IEnumerable.GetEnumerator() {
147 return (IEnumerator)(new TempDataDictionaryEnumerator(this));
151 private sealed class TempDataDictionaryEnumerator : IEnumerator<KeyValuePair<string, object>> {
152 private IEnumerator<KeyValuePair<string, object>> _enumerator;
153 private TempDataDictionary _tempData;
155 public TempDataDictionaryEnumerator(TempDataDictionary tempData) {
156 _tempData = tempData;
157 _enumerator = _tempData._data.GetEnumerator();
160 public KeyValuePair<string, object> Current {
162 KeyValuePair<string, object> kvp = _enumerator.Current;
163 _tempData._initialKeys.Remove(kvp.Key);
168 public bool MoveNext() {
169 return _enumerator.MoveNext();
172 public void Reset() {
176 #region IEnumerator Implementation
177 object IEnumerator.Current {
184 #region IDisposable Implementation
185 void IDisposable.Dispose() {
186 _enumerator.Dispose();