1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\r
5 * This software is subject to the Microsoft Public License (Ms-PL).
\r
6 * A copy of the license can be found in the license.htm file included
\r
7 * in this distribution.
\r
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc {
\r
15 using System.ComponentModel;
\r
16 using System.Data.Linq;
\r
18 using System.Reflection;
\r
21 public static class ModelBinders {
\r
23 private static readonly ModelBinderDictionary _binders = CreateDefaultBinderDictionary();
\r
25 public static ModelBinderDictionary Binders {
\r
31 internal static IModelBinder GetBinderFromAttributes(Type type, Func<string> errorMessageAccessor) {
\r
32 AttributeCollection allAttrs = TypeDescriptorHelper.Get(type).GetAttributes();
\r
33 CustomModelBinderAttribute[] filteredAttrs = allAttrs.OfType<CustomModelBinderAttribute>().ToArray();
\r
34 return GetBinderFromAttributesImpl(filteredAttrs, errorMessageAccessor);
\r
37 internal static IModelBinder GetBinderFromAttributes(ICustomAttributeProvider element, Func<string> errorMessageAccessor) {
\r
38 CustomModelBinderAttribute[] attrs = (CustomModelBinderAttribute[])element.GetCustomAttributes(typeof(CustomModelBinderAttribute), true /* inherit */);
\r
39 return GetBinderFromAttributesImpl(attrs, errorMessageAccessor);
\r
42 private static IModelBinder GetBinderFromAttributesImpl(CustomModelBinderAttribute[] attrs, Func<string> errorMessageAccessor) {
\r
43 // this method is used to get a custom binder based on the attributes of the element passed to it.
\r
44 // it will return null if a binder cannot be detected based on the attributes alone.
\r
46 if (attrs == null) {
\r
50 switch (attrs.Length) {
\r
55 IModelBinder binder = attrs[0].GetBinder();
\r
59 string errorMessage = errorMessageAccessor();
\r
60 throw new InvalidOperationException(errorMessage);
\r
64 private static ModelBinderDictionary CreateDefaultBinderDictionary() {
\r
65 // We can't add a binder to the HttpPostedFileBase type as an attribute, so we'll just
\r
66 // prepopulate the dictionary as a convenience to users.
\r
68 ModelBinderDictionary binders = new ModelBinderDictionary() {
\r
69 { typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder() },
\r
70 { typeof(byte[]), new ByteArrayModelBinder() },
\r
71 { typeof(Binary), new LinqBinaryModelBinder() }
\r