File: ModelBinderProviderCollection.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (135 lines) | stat: -rw-r--r-- 6,070 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
namespace System.Web.ModelBinding {
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Linq;

    public sealed class ModelBinderProviderCollection : Collection<ModelBinderProvider> {

        public ModelBinderProviderCollection() {
        }

        public ModelBinderProviderCollection(IList<ModelBinderProvider> list)
            : base(list) {
        }

        public IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) {
            if (modelBindingExecutionContext == null) {
                throw new ArgumentNullException("modelBindingExecutionContext");
            }
            if (bindingContext == null) {
                throw new ArgumentNullException("bindingContext");
            }

            ModelBinderProvider providerFromAttr;
            if (TryGetProviderFromAttributes(bindingContext.ModelType, out providerFromAttr)) {
                return providerFromAttr.GetBinder(modelBindingExecutionContext, bindingContext);
            }

            return (from provider in this
                    let binder = provider.GetBinder(modelBindingExecutionContext, bindingContext)
                    where binder != null
                    select binder).FirstOrDefault();
        }

        internal IModelBinder GetRequiredBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) {
            IModelBinder binder = GetBinder(modelBindingExecutionContext, bindingContext);
            if (binder == null) {
                throw Error.ModelBinderProviderCollection_BinderForTypeNotFound(bindingContext.ModelType);
            }
            return binder;
        }

        protected override void InsertItem(int index, ModelBinderProvider item) {
            if (item == null) {
                throw new ArgumentNullException("item");
            }

            base.InsertItem(index, item);
        }

        private void InsertSimpleProviderAtFront(ModelBinderProvider provider) {
            // Don't want to insert simple providers before any that are marked as "should go first,"
            // as that might throw off other providers like the exact type match provider.

            int i = 0;
            for (; i < Count; i++) {
                if (!ShouldProviderGoFirst(this[i])) {
                    break;
                }
            }

            base.InsertItem(i, provider);
        }

        public void RegisterBinderForGenericType(Type modelType, IModelBinder modelBinder) {
            InsertSimpleProviderAtFront(new GenericModelBinderProvider(modelType, modelBinder));
        }

        public void RegisterBinderForGenericType(Type modelType, Func<Type[], IModelBinder> modelBinderFactory) {
            InsertSimpleProviderAtFront(new GenericModelBinderProvider(modelType, modelBinderFactory));
        }

        public void RegisterBinderForGenericType(Type modelType, Type modelBinderType) {
            InsertSimpleProviderAtFront(new GenericModelBinderProvider(modelType, modelBinderType));
        }

        public void RegisterBinderForType(Type modelType, IModelBinder modelBinder) {
            RegisterBinderForType(modelType, modelBinder, false /* suppressPrefixCheck */);
        }

        internal void RegisterBinderForType(Type modelType, IModelBinder modelBinder, bool suppressPrefixCheck) {
            SimpleModelBinderProvider provider = new SimpleModelBinderProvider(modelType, modelBinder) {
                SuppressPrefixCheck = suppressPrefixCheck
            };
            InsertSimpleProviderAtFront(provider);
        }

        public void RegisterBinderForType(Type modelType, Func<IModelBinder> modelBinderFactory) {
            InsertSimpleProviderAtFront(new SimpleModelBinderProvider(modelType, modelBinderFactory));
        }

        protected override void SetItem(int index, ModelBinderProvider item) {
            if (item == null) {
                throw new ArgumentNullException("item");
            }

            base.SetItem(index, item);
        }

        private static bool ShouldProviderGoFirst(ModelBinderProvider provider) {
            ModelBinderProviderOptionsAttribute options = provider.GetType()
                .GetCustomAttributes(typeof(ModelBinderProviderOptionsAttribute), true /* inherit */)
                .OfType<ModelBinderProviderOptionsAttribute>()
                .FirstOrDefault();

            return (options != null) ? options.FrontOfList : false;
        }

        private static bool TryGetProviderFromAttributes(Type modelType, out ModelBinderProvider provider) {
            ExtensibleModelBinderAttribute attr = TypeDescriptorHelper.Get(modelType).GetAttributes().OfType<ExtensibleModelBinderAttribute>().FirstOrDefault();
            if (attr == null) {
                provider = null;
                return false;
            }

            if (typeof(ModelBinderProvider).IsAssignableFrom(attr.BinderType)) {
                provider = (ModelBinderProvider)SecurityUtils.SecureCreateInstance(attr.BinderType);
            }
            else if (typeof(IModelBinder).IsAssignableFrom(attr.BinderType)) {
                Type closedBinderType = (attr.BinderType.IsGenericTypeDefinition) ? attr.BinderType.MakeGenericType(modelType.GetGenericArguments()) : attr.BinderType;
                IModelBinder binderInstance = (IModelBinder)SecurityUtils.SecureCreateInstance(closedBinderType);
                provider = new SimpleModelBinderProvider(modelType, binderInstance) { SuppressPrefixCheck = attr.SuppressPrefixCheck };
            }
            else {
                string errorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.ModelBinderProviderCollection_InvalidBinderType),
                    attr.BinderType, typeof(ModelBinderProvider), typeof(IModelBinder));
                throw new InvalidOperationException(errorMessage);
            }

            return true;
        }

    }
}