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)); }
/// <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); } }
/// <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)); } }