Merge pull request #757 from mlintner/master
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / ModelStateDictionary.cs
1 namespace System.Web.Mvc {
2     using System;
3     using System.Collections;
4     using System.Collections.Generic;
5     using System.Linq;
6
7     [Serializable]
8     public class ModelStateDictionary : IDictionary<string, ModelState> {
9
10         private readonly Dictionary<string, ModelState> _innerDictionary = new Dictionary<string, ModelState>(StringComparer.OrdinalIgnoreCase);
11
12         public ModelStateDictionary() {
13         }
14
15         public ModelStateDictionary(ModelStateDictionary dictionary) {
16             if (dictionary == null) {
17                 throw new ArgumentNullException("dictionary");
18             }
19
20             foreach (var entry in dictionary) {
21                 _innerDictionary.Add(entry.Key, entry.Value);
22             }
23         }
24
25         public int Count {
26             get {
27                 return _innerDictionary.Count;
28             }
29         }
30
31         public bool IsReadOnly {
32             get {
33                 return ((IDictionary<string, ModelState>)_innerDictionary).IsReadOnly;
34             }
35         }
36
37         public bool IsValid {
38             get {
39                 return Values.All(modelState => modelState.Errors.Count == 0);
40             }
41         }
42
43         public ICollection<string> Keys {
44             get {
45                 return _innerDictionary.Keys;
46             }
47         }
48
49         public ModelState this[string key] {
50             get {
51                 ModelState value;
52                 _innerDictionary.TryGetValue(key, out value);
53                 return value;
54             }
55             set {
56                 _innerDictionary[key] = value;
57             }
58         }
59
60         public ICollection<ModelState> Values {
61             get {
62                 return _innerDictionary.Values;
63             }
64         }
65
66         public void Add(KeyValuePair<string, ModelState> item) {
67             ((IDictionary<string, ModelState>)_innerDictionary).Add(item);
68         }
69
70         public void Add(string key, ModelState value) {
71             _innerDictionary.Add(key, value);
72         }
73
74         public void AddModelError(string key, Exception exception) {
75             GetModelStateForKey(key).Errors.Add(exception);
76         }
77
78         public void AddModelError(string key, string errorMessage) {
79             GetModelStateForKey(key).Errors.Add(errorMessage);
80         }
81
82         public void Clear() {
83             _innerDictionary.Clear();
84         }
85
86         public bool Contains(KeyValuePair<string, ModelState> item) {
87             return ((IDictionary<string, ModelState>)_innerDictionary).Contains(item);
88         }
89
90         public bool ContainsKey(string key) {
91             return _innerDictionary.ContainsKey(key);
92         }
93
94         public void CopyTo(KeyValuePair<string, ModelState>[] array, int arrayIndex) {
95             ((IDictionary<string, ModelState>)_innerDictionary).CopyTo(array, arrayIndex);
96         }
97
98         public IEnumerator<KeyValuePair<string, ModelState>> GetEnumerator() {
99             return _innerDictionary.GetEnumerator();
100         }
101
102         private ModelState GetModelStateForKey(string key) {
103             if (key == null) {
104                 throw new ArgumentNullException("key");
105             }
106
107             ModelState modelState;
108             if (!TryGetValue(key, out modelState)) {
109                 modelState = new ModelState();
110                 this[key] = modelState;
111             }
112
113             return modelState;
114         }
115
116         public bool IsValidField(string key) {
117             if (key == null) {
118                 throw new ArgumentNullException("key");
119             }
120
121             // if the key is not found in the dictionary, we just say that it's valid (since there are no errors)
122             return DictionaryHelpers.FindKeysWithPrefix(this, key).All(entry => entry.Value.Errors.Count == 0);
123         }
124
125         public void Merge(ModelStateDictionary dictionary) {
126             if (dictionary == null) {
127                 return;
128             }
129
130             foreach (var entry in dictionary) {
131                 this[entry.Key] = entry.Value;
132             }
133         }
134
135         public bool Remove(KeyValuePair<string, ModelState> item) {
136             return ((IDictionary<string, ModelState>)_innerDictionary).Remove(item);
137         }
138
139         public bool Remove(string key) {
140             return _innerDictionary.Remove(key);
141         }
142
143         public void SetModelValue(string key, ValueProviderResult value) {
144             GetModelStateForKey(key).Value = value;
145         }
146
147         public bool TryGetValue(string key, out ModelState value) {
148             return _innerDictionary.TryGetValue(key, out value);
149         }
150
151         #region IEnumerable Members
152         IEnumerator IEnumerable.GetEnumerator() {
153             return ((IEnumerable)_innerDictionary).GetEnumerator();
154         }
155         #endregion
156
157     }
158 }