1 namespace System.Web.Mvc {
3 using System.ComponentModel;
4 using System.Data.Linq;
6 using System.Reflection;
9 public static class ModelBinders {
11 private static readonly ModelBinderDictionary _binders = CreateDefaultBinderDictionary();
13 public static ModelBinderDictionary Binders {
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);
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);
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.
38 switch (attrs.Length) {
43 IModelBinder binder = attrs[0].GetBinder();
47 string errorMessage = errorMessageAccessor();
48 throw new InvalidOperationException(errorMessage);
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.
56 ModelBinderDictionary binders = new ModelBinderDictionary() {
57 { typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder() },
58 { typeof(byte[]), new ByteArrayModelBinder() },
59 { typeof(Binary), new LinqBinaryModelBinder() }