コード例 #1
0
        /// <summary>
        /// Bind the parameter using default model binding but with the supplied value providers.
        /// </summary>
        /// <param name="parameter">parameter to provide binding for.</param>
        /// <param name="valueProviderFactories">value provider factories to feed to model binders</param>
        /// <returns>a binding</returns>
        public static HttpParameterBinding BindWithModelBinding(this HttpParameterDescriptor parameter, IEnumerable<ValueProviderFactory> valueProviderFactories)
        {
            HttpConfiguration config = parameter.Configuration;
            IModelBinder binder = new ModelBinderAttribute().GetModelBinder(config, parameter.ParameterType);

            return new ModelBinderParameterBinding(parameter, binder, valueProviderFactories);
        }
コード例 #2
0
        internal static bool TryGetProviderFromAttribute(Type modelType, ModelBinderAttribute modelBinderAttribute, out ModelBinderProvider provider)
        {
            Contract.Assert(modelType != null, "modelType cannot be null.");
            Contract.Assert(modelBinderAttribute != null, "modelBinderAttribute cannot be null");

            if (typeof(ModelBinderProvider).IsAssignableFrom(modelBinderAttribute.BinderType))
            {
                // REVIEW: DI?
                provider = (ModelBinderProvider)Activator.CreateInstance(modelBinderAttribute.BinderType);
            }
            else if (typeof(IModelBinder).IsAssignableFrom(modelBinderAttribute.BinderType))
            {
                Type closedBinderType =
                    modelBinderAttribute.BinderType.IsGenericTypeDefinition
                        ? modelBinderAttribute.BinderType.MakeGenericType(modelType.GetGenericArguments())
                        : modelBinderAttribute.BinderType;

                IModelBinder binderInstance = (IModelBinder)Activator.CreateInstance(closedBinderType);
                provider = new SimpleModelBinderProvider(modelType, binderInstance)
                {
                    SuppressPrefixCheck = modelBinderAttribute.SuppressPrefixCheck
                };
            }
            else
            {
                throw Error.InvalidOperation(SRResources.ModelBinderProviderCollection_InvalidBinderType, modelBinderAttribute.BinderType, typeof(ModelBinderProvider), typeof(IModelBinder));
            }

            return(true);
        }
コード例 #3
0
        public void BinderType_Provided()
        {
            HttpConfiguration config = new HttpConfiguration();
            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);
            Assert.IsType<CustomModelBinderProvider>(provider);
        }
コード例 #4
0
        // Returns true if the ModelBinderAttribute specifies a binder provider of <TProvider> or binder instance of <TBinder>
        internal static bool IsModelBinderFor <TProvider, TBinder>(ModelBinderAttribute modelBinderAttribute)
        {
            Contract.Assert(modelBinderAttribute != null, "modelBinderAttribute cannot be null");
            Type binderType = modelBinderAttribute.BinderType;

            return(binderType != null &&
                   (typeof(TProvider).IsAssignableFrom(binderType) ||
                    typeof(TBinder).IsAssignableFrom(binderType)));
        }
コード例 #5
0
        public void BinderType_Provided()
        {
            HttpConfiguration    config = new HttpConfiguration();
            ModelBinderAttribute attr   = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);

            Assert.IsType <CustomModelBinderProvider>(provider);
        }
コード例 #6
0
        public void Empty_BinderType()
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Services.Replace(typeof(ModelBinderProvider), new CustomModelBinderProvider());

            ModelBinderAttribute attr = new ModelBinderAttribute();

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);
            Assert.IsType<CustomModelBinderProvider>(provider);
        }
コード例 #7
0
        public void Illegal_BinderType()
        {
            // Given an illegal type.
            // Constructor shouldn't throw. But trying to instantiate the model binder provider will throw.
            HttpConfiguration    config = new HttpConfiguration();
            ModelBinderAttribute attr   = new ModelBinderAttribute(typeof(object));

            Assert.Equal(typeof(object), attr.BinderType); // can still lookup illegal type
            Assert.Throws <InvalidOperationException>(() => attr.GetModelBinderProvider(config));
        }
コード例 #8
0
        public void BindWithModelBinding_Attribute()
        {
            HttpParameterDescriptor param = CreateParameterDescriptor();

            ModelBinderAttribute attribute = new ModelBinderAttribute(typeof(CustomModelBinder));
            ModelBinderParameterBinding binding = (ModelBinderParameterBinding) param.BindWithAttribute(attribute);

            Assert.NotNull(binding);
            Assert.IsType<CustomModelBinder>(binding.Binder);
        }
コード例 #9
0
        public void Illegal_BinderType()
        {
            // Given an illegal type.
            // Constructor shouldn't throw. But trying to instantiate the model binder provider will throw.
            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(object));

            Assert.Equal(typeof(object), attr.BinderType); // can still lookup illegal type
            Assert.Throws<InvalidOperationException>(
                () => attr.GetModelBinderProvider(new HttpConfiguration())
            );
        }
コード例 #10
0
        private HttpParameterBinding DetermineBinding(HttpParameterDescriptor parameter)
        {
            HttpConfiguration config = parameter.Configuration;
            var attr = new ModelBinderAttribute(); // use default settings
            ModelBinderProvider provider = attr.GetModelBinderProvider(config);

            // Alternatively, we could put this ValueProviderFactory in the global config.
            var vpfs = new List<ValueProviderFactory>(attr.GetValueProviderFactories(config)) { new BodyValueProviderFactory() };
            var valueProviderFactories = new List<ValueProviderFactory> { new CompositeValueProviderFactory(vpfs) };
            return new ModelBinderParameterBinding(parameter, provider, valueProviderFactories);
        }
コード例 #11
0
        internal static bool TryGetProviderFromAttributes(Type modelType, out ModelBinderProvider provider)
        {
            ModelBinderAttribute attr = GetModelBinderAttribute(modelType);

            if (attr == null)
            {
                provider = null;
                return(false);
            }

            return(TryGetProviderFromAttribute(modelType, attr, out provider));
        }
コード例 #12
0
        public void Empty_BinderType()
        {
            HttpConfiguration config = new HttpConfiguration();

            config.Services.Replace(typeof(ModelBinderProvider), new CustomModelBinderProvider());

            ModelBinderAttribute attr = new ModelBinderAttribute();

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);

            Assert.IsType <CustomModelBinderProvider>(provider);
        }
コード例 #13
0
        internal static bool TryGetProviderFromAttributes(Type modelType, out ModelBinderProvider provider)
        {
            ModelBinderAttribute attr = TypeDescriptorHelper.Get(modelType).GetAttributes().OfType <ModelBinderAttribute>().FirstOrDefault();

            if (attr == null)
            {
                provider = null;
                return(false);
            }

            return(TryGetProviderFromAttribute(modelType, attr, out provider));
        }
コード例 #14
0
        public void BinderType_From_ServiceResolver()
        {
            // To test ServiceResolver, the registered type and actual type should be different.
            HttpConfiguration config = new HttpConfiguration();

            config.ServiceResolver.SetService(typeof(CustomModelBinderProvider), new SecondCustomModelBinderProvider());

            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);

            Assert.IsType <SecondCustomModelBinderProvider>(provider);
        }
コード例 #15
0
        // Determine how a single parameter will get bound.
        // This is all sync. We don't need to actually read the body just to determine that we'll bind to the body.
        private HttpParameterBinding DetermineBinding(HttpParameterDescriptor parameter)
        {
            // Look at Parameter attributes?
            // [FromBody] - we use Formatter.
            bool hasFromBody          = parameter.GetCustomAttributes <FromBodyAttribute>().Any();
            ModelBinderAttribute attr = parameter.ModelBinderAttribute;

            if (hasFromBody)
            {
                if (attr != null)
                {
                    string message = Error.Format(SRResources.ParameterBindingConflictingAttributes, parameter.ParameterName);
                    return(new ErrorParameterBinding(parameter, message));
                }

                return(MakeBodyBinding(parameter)); // It's from the body. Uses a formatter.
            }

            // Presence of a model binder attribute overrides.
            if (attr != null)
            {
                return(GetBinding(parameter, attr));
            }

            // No attribute, key off type
            Type type = parameter.ParameterType;

            if (TypeHelper.IsSimpleUnderlyingType(type) || TypeHelper.HasStringConverter(type))
            {
                attr = new ModelBinderAttribute(); // use default settings
                return(GetBinding(parameter, attr));
            }

            // Handle special types
            if (type == typeof(CancellationToken))
            {
                return(new CancellationTokenParameterBinding(parameter));
            }
            if (type == typeof(HttpRequestMessage))
            {
                return(new HttpRequestParameterBinding(parameter));
            }
            if (typeof(HttpContent).IsAssignableFrom(type))
            {
                string message = Error.Format(SRResources.ParameterBindingIllegalType, type.Name, parameter.ParameterName);
                return(new ErrorParameterBinding(parameter, message));
            }

            // Fallback. Must be a complex type. Default is to look in body.
            return(MakeBodyBinding(parameter));
        }
コード例 #16
0
        public void Get_ModelBinder_From_BinderProvider()
        {
            HttpConfiguration    config = new HttpConfiguration();
            ModelBinderAttribute attr   = new ModelBinderAttribute {
                BinderType = typeof(CustomModelBinderProvider)
            };

            // Act
            IModelBinder binder = attr.GetModelBinder(config, null);

            // Assert
            Assert.NotNull(binder);
            Assert.IsType <CustomModelBinder>(binder);
        }
コード例 #17
0
        public void BinderType_From_DependencyResolver()
        {
            // To test dependency resolver, the registered type and actual type should be different. 
            HttpConfiguration config = new HttpConfiguration();
            var mockDependencyResolver = new Mock<IDependencyResolver>();
            mockDependencyResolver.Setup(r => r.GetService(typeof(CustomModelBinderProvider)))
                               .Returns(new SecondCustomModelBinderProvider());
            config.DependencyResolver = mockDependencyResolver.Object;

            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);
            Assert.IsType<SecondCustomModelBinderProvider>(provider);
        }
コード例 #18
0
        private HttpParameterBinding DetermineBinding(MvcActionBinding actionBinding, HttpParameterDescriptor parameter)
        {
            HttpConfiguration config = parameter.Configuration;

            var attr = new ModelBinderAttribute(); // use default settings

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);
            IModelBinder binder = provider.GetBinder(config, parameter.ParameterType);

            // Alternatively, we could put this ValueProviderFactory in the global config.
            List<ValueProviderFactory> vpfs = new List<ValueProviderFactory>(attr.GetValueProviderFactories(config));
            vpfs.Add(new BodyValueProviderFactory());

            return new ModelBinderParameterBinding(parameter, binder, vpfs);
        }
コード例 #19
0
        public void BinderType_From_DependencyResolver()
        {
            // To test dependency resolver, the registered type and actual type should be different.
            HttpConfiguration config   = new HttpConfiguration();
            var mockDependencyResolver = new Mock <IDependencyResolver>();

            mockDependencyResolver.Setup(r => r.GetService(typeof(CustomModelBinderProvider)))
            .Returns(new SecondCustomModelBinderProvider());
            config.DependencyResolver = mockDependencyResolver.Object;

            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);

            Assert.IsType <SecondCustomModelBinderProvider>(provider);
        }
コード例 #20
0
        public void BinderType_From_DependencyResolver_ReleasedWhenConfigIsDisposed()
        {
            // Arrange
            HttpConfiguration config = new HttpConfiguration();
            var mockDependencyResolver = new Mock<IDependencyResolver>();
            SecondCustomModelBinderProvider provider = new SecondCustomModelBinderProvider();
            mockDependencyResolver.Setup(r => r.GetService(typeof(CustomModelBinderProvider))).Returns(provider);
            config.DependencyResolver = mockDependencyResolver.Object;
            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(CustomModelBinderProvider));
            attr.GetModelBinderProvider(config);

            // Act
            config.Dispose();

            // Assert
            mockDependencyResolver.Verify(dr => dr.Dispose(), Times.Once());
        }
コード例 #21
0
        public void BinderType_From_DependencyResolver_ReleasedWhenConfigIsDisposed()
        {
            // Arrange
            HttpConfiguration config   = new HttpConfiguration();
            var mockDependencyResolver = new Mock <IDependencyResolver>();
            SecondCustomModelBinderProvider provider = new SecondCustomModelBinderProvider();

            mockDependencyResolver.Setup(r => r.GetService(typeof(CustomModelBinderProvider))).Returns(provider);
            config.DependencyResolver = mockDependencyResolver.Object;
            ModelBinderAttribute attr = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            attr.GetModelBinderProvider(config);

            // Act
            config.Dispose();

            // Assert
            mockDependencyResolver.Verify(dr => dr.Dispose(), Times.Once());
        }
コード例 #22
0
        internal static bool TryGetProviderFromAttributes(HttpParameterDescriptor parameterDescriptor, out ModelBinderProvider provider)
        {
            Contract.Assert(parameterDescriptor != null, "parameterDescriptor cannot be null.");

            Type modelType = parameterDescriptor.ParameterType;

            ModelBinderAttribute attr = parameterDescriptor.GetCustomAttributes <ModelBinderAttribute>().FirstOrDefault();

            if (attr == null)
            {
                attr = TypeDescriptorHelper.Get(modelType).GetAttributes().OfType <ModelBinderAttribute>().FirstOrDefault();
            }

            if (attr == null)
            {
                provider = null;
                return(false);
            }

            return(TryGetProviderFromAttribute(modelType, attr, out provider));
        }
コード例 #23
0
        private static HttpParameterBinding GetBinding(HttpParameterDescriptor parameter, ModelBinderAttribute attr)
        {
            HttpConfiguration config = parameter.Configuration;

            return(new ModelBinderParameterBinding(parameter,
                                                   attr.GetModelBinderProvider(config),
                                                   attr.GetValueProviderFactories(config)));
        }
コード例 #24
0
        // Determine how a single parameter will get bound. 
        // This is all sync. We don't need to actually read the body just to determine that we'll bind to the body.         
        private HttpParameterBinding DetermineBinding(HttpParameterDescriptor parameter)
        {
            // Look at Parameter attributes?
            // [FromBody] - we use Formatter.
            bool hasFromBody = parameter.GetCustomAttributes<FromBodyAttribute>().Any();
            ModelBinderAttribute attr = parameter.ModelBinderAttribute;
                        
            if (hasFromBody)
            {
                if (attr != null)
                {
                    string message = Error.Format(SRResources.ParameterBindingConflictingAttributes, parameter.ParameterName);
                    return new ErrorParameterBinding(parameter, message);
                }

                return MakeBodyBinding(parameter); // It's from the body. Uses a formatter. 
            }

            // Presence of a model binder attribute overrides.
            if (attr != null)
            {
                return GetBinding(parameter, attr);
            }
            
            // No attribute, key off type
            Type type = parameter.ParameterType;
            if (TypeHelper.IsSimpleUnderlyingType(type) || TypeHelper.HasStringConverter(type))
            {
                attr = new ModelBinderAttribute(); // use default settings
                return GetBinding(parameter, attr);
            }

            // Handle special types
            if (type == typeof(CancellationToken))
            {
                return new CancellationTokenParameterBinding(parameter);
            }
            if (type == typeof(HttpRequestMessage))
            {
                return new HttpRequestParameterBinding(parameter);
            }
            if (typeof(HttpContent).IsAssignableFrom(type))
            {
                string message = Error.Format(SRResources.ParameterBindingIllegalType, type.Name, parameter.ParameterName);
                return new ErrorParameterBinding(parameter, message);
            }            

            // Fallback. Must be a complex type. Default is to look in body.             
            return MakeBodyBinding(parameter);
        }
コード例 #25
0
 private static HttpParameterBinding GetBinding(HttpParameterDescriptor parameter, ModelBinderAttribute attr)
 {
     HttpConfiguration config = parameter.Configuration;
     return new ModelBinderParameterBinding(parameter,
         attr.GetModelBinderProvider(config),
         attr.GetValueProviderFactories(config));
 }
コード例 #26
0
        public void Get_ModelBinder_From_BinderProvider()
        {
            HttpConfiguration config = new HttpConfiguration();
            ModelBinderAttribute attr = new ModelBinderAttribute { BinderType = typeof(CustomModelBinderProvider) };

            // Act
            IModelBinder binder = attr.GetModelBinder(config, null);

            // Assert
            Assert.NotNull(binder);
            Assert.IsType<CustomModelBinder>(binder);
        }
コード例 #27
0
        static IModelBinder GetModelBinder(IFromRouteAttribute fromRouteAttr, Type modelType, HttpConfiguration configuration)
        {
            modelType = TypeHelpers.GetNullableUnderlyingType(modelType);

             ModelBinderAttribute modelBinderAttr = null;

             if (fromRouteAttr != null) {
            modelBinderAttr = (ModelBinderAttribute)fromRouteAttr;
             }

             if (modelBinderAttr == null
            || modelBinderAttr.BinderType == null) {

            ModelBinderAttribute modelTypeAttr = modelBinderAttrCache.GetOrAdd(modelType, t =>
               t.GetCustomAttributes(typeof(ModelBinderAttribute), inherit: true)
                  .Cast<ModelBinderAttribute>()
                  .SingleOrDefault()
            );

            if (modelTypeAttr != null
               && (modelBinderAttr == null
                  || modelTypeAttr.BinderType != null)) {

               modelBinderAttr = modelTypeAttr;
            }
             }

             if (modelBinderAttr == null) {
            modelBinderAttr = new ModelBinderAttribute();
             }

             return modelBinderAttr.GetModelBinder(configuration, modelType);
        }