public static T ReadAs <T>(
     this FormDataCollection formData,
     string modelName,
     IRequiredMemberSelector requiredMemberSelector,
     IFormatterLogger formatterLogger
     )
 {
     return((T)ReadAs(
                formData,
                typeof(T),
                modelName,
                requiredMemberSelector,
                formatterLogger
                ));
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="MediaTypeFormatter"/> class.
        /// </summary>
        /// <param name="formatter">The <see cref="MediaTypeFormatter"/> instance to copy settings from.</param>
        protected MediaTypeFormatter(MediaTypeFormatter formatter)
        {
            if (formatter == null)
            {
                throw Error.ArgumentNull("formatter");
            }

            _supportedMediaTypes    = formatter._supportedMediaTypes;
            SupportedMediaTypes     = formatter.SupportedMediaTypes;
            _supportedEncodings     = formatter._supportedEncodings;
            SupportedEncodings      = formatter.SupportedEncodings;
            _mediaTypeMappings      = formatter._mediaTypeMappings;
            MediaTypeMappings       = formatter.MediaTypeMappings;
            _requiredMemberSelector = formatter._requiredMemberSelector;
        }
Exemple #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MediaTypeFormatter"/> class.
        /// </summary>
        /// <param name="formatter">The <see cref="MediaTypeFormatter"/> instance to copy settings from.</param>
        protected MediaTypeFormatter(MediaTypeFormatter formatter)
        {
            if (formatter == null)
            {
                throw Error.ArgumentNull("formatter");
            }

            this._supportedMediaTypes = formatter._supportedMediaTypes;
            this.SupportedMediaTypes  = formatter.SupportedMediaTypes;
            this._supportedEncodings  = formatter._supportedEncodings;
            this.SupportedEncodings   = formatter.SupportedEncodings;
#if !NETFX_CORE // No MediaTypeMappings in portable library or IRequiredMemberSelector (no model state on client)
            this._mediaTypeMappings      = formatter._mediaTypeMappings;
            this.MediaTypeMappings       = formatter.MediaTypeMappings;
            this._requiredMemberSelector = formatter._requiredMemberSelector;
#endif
        }
 public static object ReadAs(
     this FormDataCollection formData,
     Type type,
     string modelName,
     IRequiredMemberSelector requiredMemberSelector,
     IFormatterLogger formatterLogger
     )
 {
     return(ReadAs(
                formData,
                type,
                modelName,
                requiredMemberSelector,
                formatterLogger,
                config: null
                ));
 }
 public RequiredMemberModelValidatorProvider(IRequiredMemberSelector requiredMemberSelector)
 {
     _requiredMemberSelector = requiredMemberSelector;
 }
 public RequiredMemberModelValidatorProvider(IRequiredMemberSelector requiredMemberSelector)
 {
     _requiredMemberSelector = requiredMemberSelector;
 }
        /// <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. Or the name of a model to do a partial binding against the form data.
        /// This is common for extracting individual fields.</param>
        /// <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>
        /// <param name="config">The <see cref="HttpConfiguration"/> configuration to pick binder from.
        /// Can be null if the config was not created already. In that case a new config is created.</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,
            HttpConfiguration config
            )
        {
            if (formData == null)
            {
                throw Error.ArgumentNull("formData");
            }
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            object            result        = null;
            HttpActionContext actionContext = null;

            bool validateRequiredMembers =
                requiredMemberSelector != null && formatterLogger != null;

            if (validateRequiredMembers)
            {
                // We wrap the config so we can override the services and cache
                // without affecting outside callers or users of the config.
                using (HttpConfiguration wrapperConfig = new HttpConfiguration())
                {
                    config = config == null ? wrapperConfig : config;
                    wrapperConfig.Services = new ServicesContainerWrapper(
                        config,
                        new RequiredMemberModelValidatorProvider(requiredMemberSelector)
                        );

                    // The HttpActionContext provides access to configuration for ModelBinders, and is also provided
                    // to the IModelBinder when binding occurs. Since HttpActionContext was not provided, create a default.
                    actionContext = CreateActionContextForModelBinding(wrapperConfig);
                    result        = ReadAs(formData, type, modelName, actionContext);
                }
            }
            else
            {
                if (config == null)
                {
                    using (config = new HttpConfiguration())
                    {
                        actionContext = CreateActionContextForModelBinding(config);
                        result        = ReadAs(formData, type, modelName, actionContext);
                    }
                }
                else
                {
                    actionContext = CreateActionContextForModelBinding(config);
                    result        = ReadAs(formData, type, modelName, actionContext);
                }
            }

            // The model binding will log any errors to the HttpActionContext's ModelState. Since this is a context
            // that we created and doesn't map to a real action invocation, we want to forward the errors to
            // the user-specified IFormatterLogger.
            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);
                        }
                    }
                }
            }

            return(result);
        }
        /// <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.
                HttpControllerContext controllerContext = new HttpControllerContext()
                {
                    Configuration = config
                };
                HttpActionContext actionContext = new HttpActionContext {
                    ControllerContext = controllerContext
                };

                ModelMetadataProvider metadataProvider = config.Services.GetModelMetadataProvider();

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

                IValueProvider vp = formData.GetJQueryValueProvider();

                ModelBindingContext ctx = new ModelBindingContext()
                {
                    ModelName             = modelName,
                    FallbackToEmptyPrefix = false,
                    ModelMetadata         = metadataProvider.GetMetadataForType(null, type),
                    ModelState            = actionContext.ModelState,
                    ValueProvider         = vp
                };

                IModelBinder binder = modelBinderProvider.GetBinder(actionContext, ctx);

                bool haveResult = binder.BindModel(actionContext, ctx);

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

                if (haveResult)
                {
                    return(ctx.Model);
                }
                return(null);
            }
        }
Exemple #9
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));
            }
        }
Exemple #10
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.
        /// Or the name of a model to do a partial binding against the form data. This is common for extracting individual fields.</param>
        /// <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>
        /// <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");
            }

            using (HttpConfiguration config = new HttpConfiguration())
            {
                // The HttpActionContext provides access to configuration for ModelBinders, and is also provided
                // to the IModelBinder when binding occurs. Since an HttpActionContext was not provided, create a default.
                HttpActionContext actionContext = CreateActionContextForModelBinding(config);

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

                object result = ReadAs(formData, type, modelName, actionContext);

                // The model binding will log any errors to the HttpActionContext's ModelState. Since this is a context
                // that we created and doesn't map to a real action invocation, we want to forward the errors to
                // the user-specified IFormatterLogger.
                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);
                            }
                        }
                    }
                }

                return(result);
            }
        }