예제 #1
0
        /// <summary>
        /// Get the IModelBinder for this type.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="modelType">model type that the binder is expected to bind.</param>
        /// <returns>
        /// a non-null model binder.
        /// </returns>
        public IModelBinder GetModelBinder(HttpConfiguration configuration, Type modelType)
        {
            if (BinderType == null)
            {
                ModelBinderProvider provider = GetModelBinderProvider(configuration);
                return(provider.GetBinder(configuration, modelType));
            }

            // This may create a IModelBinder or a ModelBinderProvider
            object value = GetOrInstantiate(configuration, BinderType);

            Contract.Assert(value != null); // Activator would have thrown

            IModelBinder binder = value as IModelBinder;

            if (binder != null)
            {
                return(binder);
            }
            else
            {
                ModelBinderProvider provider = value as ModelBinderProvider;
                if (provider != null)
                {
                    return(provider.GetBinder(configuration, modelType));
                }
            }

            Type required = typeof(IModelBinder);

            throw Error.InvalidOperation(SRResources.ValueProviderFactory_Cannot_Create, required.Name, value.GetType().Name, required.Name);
        }
예제 #2
0
        // This will get called by a parameter binding, which will cache the results.
        public ModelBinderProvider GetModelBinderProvider(HttpConfiguration configuration)
        {
            if (BinderType != null)
            {
                object value = GetOrInstantiate(configuration, BinderType);

                if (value != null)
                {
                    VerifyBinderType(value.GetType());
                    ModelBinderProvider result = (ModelBinderProvider)value;
                    return(result);
                }
            }

            // Create default over config
            IEnumerable <ModelBinderProvider> providers =
                configuration.Services.GetModelBinderProviders();

            if (providers.Count() == 1)
            {
                return(providers.First());
            }

            return(new CompositeModelBinderProvider(providers));
        }
        private static object ReadAsInternal(
            this FormDataCollection formData,
            Type type,
            string modelName,
            HttpActionContext actionContext
            )
        {
            Contract.Assert(formData != null);
            Contract.Assert(type != null);
            Contract.Assert(actionContext != null);

            IValueProvider      valueProvider  = formData.GetJQueryValueProvider();
            ModelBindingContext bindingContext = CreateModelBindingContext(
                actionContext,
                modelName ?? String.Empty,
                type,
                valueProvider
                );

            ModelBinderProvider modelBinderProvider = CreateModelBindingProvider(actionContext);

            IModelBinder modelBinder = modelBinderProvider.GetBinder(
                actionContext.ControllerContext.Configuration,
                type
                );
            bool haveResult = modelBinder.BindModel(actionContext, bindingContext);

            if (haveResult)
            {
                return(bindingContext.Model);
            }

            return(MediaTypeFormatter.GetDefaultValueForType(type));
        }
        public void BinderType_Provided()
        {
            HttpConfiguration    config = new HttpConfiguration();
            ModelBinderAttribute attr   = new ModelBinderAttribute(typeof(CustomModelBinderProvider));

            ModelBinderProvider provider = attr.GetModelBinderProvider(config);

            Assert.IsType <CustomModelBinderProvider>(provider);
        }
        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);
        }
예제 #6
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));
        }
예제 #7
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));
        }
        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);
        }
예제 #9
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");

            // TODO, 386718, remove the following if statement when the bug is resolved
            if (modelBinderAttribute.BinderType == null)
            {
                provider = null;
                return(false);
            }

            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);
        }
예제 #10
0
        public static string ModelBinderToString(ModelBinderProvider provider)
        {
            Contract.Assert(provider != null);

            CompositeModelBinderProvider composite = provider as CompositeModelBinderProvider;
            if (composite == null)
            {
                return provider.GetType().Name;
            }

            string modelBinderList = String.Join(", ", composite.Providers.Select<ModelBinderProvider, string>(ModelBinderToString));

            return provider.GetType().Name + "(" + modelBinderList + ")";
        }
        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);
        }
예제 #12
0
        public ModelBinderParameterBinding(HttpParameterDescriptor descriptor,
                                           ModelBinderProvider modelBinderProvider,
                                           IEnumerable <ValueProviderFactory> valueProviderFactories)
            : base(descriptor)
        {
            if (modelBinderProvider == null)
            {
                throw Error.ArgumentNull("modelBinderProvider");
            }
            if (valueProviderFactories == null)
            {
                throw Error.ArgumentNull("valueProviderFactories");
            }

            _modelBinderProvider    = modelBinderProvider;
            _valueProviderFactories = valueProviderFactories.ToArray();
        }
        public ModelBinderParameterBinding(HttpParameterDescriptor descriptor,
            ModelBinderProvider modelBinderProvider,
            IEnumerable<ValueProviderFactory> valueProviderFactories)
            : base(descriptor)
        {
            if (modelBinderProvider == null)
            {
                throw Error.ArgumentNull("modelBinderProvider");
            }
            if (valueProviderFactories == null)
            {
                throw Error.ArgumentNull("valueProviderFactories");
            }

            _modelBinderProvider = modelBinderProvider;
            _valueProviderFactories = valueProviderFactories;
        }
예제 #14
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));
        }
예제 #15
0
        /// <summary>
        /// Deserialize the form data to the given type, using model binding.
        /// </summary>
        /// <param name="formData">collection with parsed form url data</param>
        /// <param name="type">target type to read as</param>
        /// <param name="modelName">null or empty to read the entire form as a single object. This is common for body data.
        /// <param name="requiredMemberSelector">The <see cref="IRequiredMemberSelector"/> used to determine required members.</param>
        /// <param name="formatterLogger">The <see cref="IFormatterLogger"/> to log events to.</param>
        /// Or the name of a model to do a partial binding against the form data. This is common for extracting individual fields.</param>
        /// <returns>best attempt to bind the object. The best attempt may be null.</returns>
        public static object ReadAs(this FormDataCollection formData, Type type, string modelName, IRequiredMemberSelector requiredMemberSelector, IFormatterLogger formatterLogger)
        {
            if (formData == null)
            {
                throw Error.ArgumentNull("formData");
            }
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (modelName == null)
            {
                modelName = String.Empty;
            }

            using (HttpConfiguration config = new HttpConfiguration())
            {
                bool validateRequiredMembers = requiredMemberSelector != null && formatterLogger != null;
                if (validateRequiredMembers)
                {
                    // Set a ModelValidatorProvider that understands the IRequiredMemberSelector
                    config.Services.Replace(typeof(ModelValidatorProvider), new RequiredMemberModelValidatorProvider(requiredMemberSelector));
                }

                // Looks like HttpActionContext is just a way of getting to the config, which we really
                // just need to get a list of modelbinderPRoviders for composition.
                HttpActionContext actionContext = CreateActionContextForModelBinding(config);

                IValueProvider      vp  = formData.GetJQueryValueProvider();
                ModelBindingContext ctx = CreateModelBindingContext(actionContext, modelName, type, vp);

                ModelBinderProvider modelBinderProvider = CreateModelBindingProvider(actionContext);

                IModelBinder binder     = modelBinderProvider.GetBinder(config, type);
                bool         haveResult = binder.BindModel(actionContext, ctx);

                // Log model binding errors
                if (formatterLogger != null)
                {
                    foreach (KeyValuePair <string, ModelState> modelStatePair in actionContext.ModelState)
                    {
                        foreach (ModelError modelError in modelStatePair.Value.Errors)
                        {
                            if (modelError.Exception != null)
                            {
                                formatterLogger.LogError(modelStatePair.Key, modelError.Exception);
                            }
                            else
                            {
                                formatterLogger.LogError(modelStatePair.Key, modelError.ErrorMessage);
                            }
                        }
                    }
                }

                if (haveResult)
                {
                    return(ctx.Model);
                }
                return(MediaTypeFormatter.GetDefaultValueForType(type));
            }
        }