MVC calls a model binder directly on one object

Is there any way by which I can call a connecting device for a single object?

I do not need / need a special model binding. I just want to do something like this:

MyViewModel1 vModel1 = new MyViewModel1(); InvokeModelBinder(vModel1); MyViewModel2 vModel2= new MyViewModel2(); InvokeModelBinder(vModel2); 

And when I finished, the properties of both vModel1 and vModel2 were related to what was in the incoming request. Due to the fact that we are writing our controller / action, I don’t necessarily want to list vModel1 and vModel2 in the input list of the action method (since this will ultimately be a potentially long list of view models that will not necessarily be bound).

+7
source share
2 answers

Use Controller.UpdateModel :

 MyViewModel1 vModel1 = new MyViewModel1(); UpdateModel(vModel1); 

Update

Please note that if the ModelState in the controller has validation errors (associated with the model passed in action), UpdateModel (with any model) gives an excetion, despite the success of UpdateModel and vModel1. Therefore, errors in ModelState should be removed or put UpdateModel in try / catch and just ignore excetion

+8
source

This is not true at many levels IMHO:

  • This is not how ASP.NET MVC is designed to work.
  • Your actions do not define a clear agreement about what data they expect.
  • What do you choose? It smells of bad design.

The binding of the model is due to reflection. Before the action is called, it will display a list of method parameters, and for each object and its properties, it will refer to the model’s connecting device to find the value for each property from various value providers (create a POST value provider, URL parameters, etc.). Model binding also validates ModelState.

Thus, without using ASP.NET MVC by default for this, you lose all this.

Even if you have to manually take the model binding:

 IModelBinder modelBinder = ModelBinders.Binders.GetBinder(typeof(MyObject)); MyObject myObject = (MyObject ) modelBinder.BindModel(this.ControllerContext, ** ModelBindingContext HERE**); 

You can see that you need to initialize the ModelBindingContext, what ASP.NET MVC will do internally based on the current property that it reflects. Here is cut off from the source code ASP.NET MVC:

 protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { // collect all of the necessary binding properties Type parameterType = parameterDescriptor.ParameterType; IModelBinder binder = GetModelBinder(parameterDescriptor); IDictionary<string, ValueProviderResult> valueProvider = controllerContext.Controller.ValueProvider; string parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName; Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor); // finally, call into the binder ModelBindingContext bindingContext = new ModelBindingContext() { FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified ModelName = parameterName, ModelState = controllerContext.Controller.ViewData.ModelState, ModelType = parameterType, PropertyFilter = propertyFilter, ValueProvider = valueProvider }; object result = binder.BindModel(controllerContext, bindingContext); return result; 

}

+2
source

All Articles