Merge pull request #249 from pcc/xgetinputfocus
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / ModelBinders.cs
1 namespace System.Web.Mvc {
2     using System;
3     using System.ComponentModel;
4     using System.Data.Linq;
5     using System.Linq;
6     using System.Reflection;
7     using System.Web;
8
9     public static class ModelBinders {
10
11         private static readonly ModelBinderDictionary _binders = CreateDefaultBinderDictionary();
12
13         public static ModelBinderDictionary Binders {
14             get {
15                 return _binders;
16             }
17         }
18
19         internal static IModelBinder GetBinderFromAttributes(Type type, Func<string> errorMessageAccessor) {
20             AttributeCollection allAttrs = TypeDescriptorHelper.Get(type).GetAttributes();
21             CustomModelBinderAttribute[] filteredAttrs = allAttrs.OfType<CustomModelBinderAttribute>().ToArray();
22             return GetBinderFromAttributesImpl(filteredAttrs, errorMessageAccessor);
23         }
24
25         internal static IModelBinder GetBinderFromAttributes(ICustomAttributeProvider element, Func<string> errorMessageAccessor) {
26             CustomModelBinderAttribute[] attrs = (CustomModelBinderAttribute[])element.GetCustomAttributes(typeof(CustomModelBinderAttribute), true /* inherit */);
27             return GetBinderFromAttributesImpl(attrs, errorMessageAccessor);
28         }
29
30         private static IModelBinder GetBinderFromAttributesImpl(CustomModelBinderAttribute[] attrs, Func<string> errorMessageAccessor) {
31             // this method is used to get a custom binder based on the attributes of the element passed to it.
32             // it will return null if a binder cannot be detected based on the attributes alone.
33
34             if (attrs == null) {
35                 return null;
36             }
37
38             switch (attrs.Length) {
39                 case 0:
40                     return null;
41
42                 case 1:
43                     IModelBinder binder = attrs[0].GetBinder();
44                     return binder;
45
46                 default:
47                     string errorMessage = errorMessageAccessor();
48                     throw new InvalidOperationException(errorMessage);
49             }
50         }
51
52         private static ModelBinderDictionary CreateDefaultBinderDictionary() {
53             // We can't add a binder to the HttpPostedFileBase type as an attribute, so we'll just
54             // prepopulate the dictionary as a convenience to users.
55
56             ModelBinderDictionary binders = new ModelBinderDictionary() {
57                 { typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder() },
58                 { typeof(byte[]), new ByteArrayModelBinder() },
59                 { typeof(Binary), new LinqBinaryModelBinder() }
60             };
61             return binders;
62         }
63
64     }
65 }