Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ModelBinder attribute vs. ModelBinders.Add()

Tags:

Can someone tell me the pros/concs to using [ModelBinder()] attribute vs. registering model binders via ModelBinders.Add() in global.asax?

One advantage I can think of is that it's more explicit, whereas registering in the global ModelBinders is not as abvious to someone inspecting the action method.

One tradeoff I can think of is that it's not reusable, since you would have to add this attribute to all action methods that need to use this model binder, whereas registering in the global ModelBinders will make it available for all action methods receiving that model.

Is this the only difference?

In other words, would stating this be correct:

  • If you only use the model in one action method (maybe two, get + post), then use [ModelBinder()].
  • If you use the model in more than one action method, then register it in the global ModelBinders.
like image 255
Jerad Rose Avatar asked Dec 06 '12 15:12

Jerad Rose


People also ask

What is the purpose of implementing the BindModel () method on the IModelBinder interface?

MVC uses following types for Model Binding: IModelBinder interface - This defines methods that are required for a Model Binder, like the BindModel method. This method is responsible for binding a model to some values using ControllerContext and BindingContext.

What interface and method needs to be implemented for a custom model binder?

To create custom model binder class, it needs to inherit from IModelBinder interface. This interface has async method named "BindModelAsync" and it has parameter of type ModelBindingContext. The ModelBindingContext class provides the context that model binder functions.

How can we use or register a custom model binder in asp net core?

Default model binder limitations They expect to bind text-based input from the request directly to model types. You might need to transform the input prior to binding it. For example, when you have a key that can be used to look up model data. You can use a custom model binder to fetch data based on the key.

What is model binder in Web API?

Model Binding is the most powerful mechanism in Web API 2. It enables the response to receive data as per requester choice. i.e. it may be from the URL either form of Query String or Route data OR even from Request Body. It's just the requester has to decorate the action method with [FromUri] and [FromBody] as desired.


2 Answers

The result of those techniques will be the same so it is mostly a matter of what the team feels more comfortable with. So you could come up with a convention like the one you stated.

Personally, I prefer not having to set the attribute on every action method that uses that model. So I would choose one of the following options:

  • Set the attribute on the model class like:

    [ModelBinder(typeof(MyModelBinder))] public class MyModel {     ... }     
  • Globally register the binder

    ModelBinders.Binders.Add(typeof(MyModel), new MyModelBinder()) 

Another reason why I prefer one of those is because if you ever have to manually trigger the model binding process, you may also want your custom model binder to be used:

public ActionResult SomeActionMethod() {      MyModel model = ...       //manually invoke the model binding process considering only query string data      //The custom model binder will be used only if it was globally registered      //in the binders dictionary or set in an attribute of the model class      TryUpdateModel(model, new QueryStringValueProvider())       ... } 

You also have an option of implementing your own logic for selecting model binders by implementing the interface IModelBinderProvider and registering in the global.asax as in

ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider())  

One way of using the attribute in the method parameters could be overriding for that particular method the model binder that would otherwise be used. So you could globally register a model binder for your class and override it in one particular action method using the attribute.

In the end there are quite a few options for selecting the model binder. In asp MVC 3 this will be resolved in the following way (assuming you are using the default ControllerActionInvoker)

  1. The attribute on the parameter of the action. See GetParameterValue method of the ControllerActionInvoker class

  2. The Binder returned from the IModelBinderProvider. See GetBinder method in the ModelBinderDictionary class

  3. The Binder globally registered in the ModelBinders.Binders dictionary.

  4. The Binder defined in the [ModelBinder()] attribute for the model type.

  5. The DefaultModelBinder.

like image 158
Daniel J.G. Avatar answered Oct 12 '22 00:10

Daniel J.G.


It looks to me like the advantage of using an attribute rather than adding to the model binders collection in Global.asax is that you can tell the method (or class) which specific binder to use rather than associating the binder with a specific type. Then you can create the model based on a context rather than a type.

like image 27
user3667333 Avatar answered Oct 12 '22 00:10

user3667333