Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call Default Model Binding from custom binder in WebAPI?

I have a custom model binder in WebAPI that uses the following method from the `Sytem.Web.Http.ModelBinding' namespace which is the correct namespace for creating custom model binders for Web API:

public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{

}

I have a HTTP POST on a controller for which I want to use this custom model binder. The posted object contains roughly 100 fields. I want to change 2 of them. What I need is for default model binding to occur and then manipulate that model bound object for those 2 fields so that once the controller receives the object it is pristine.

The problem is I can't seem to model bind my object using the default binder from the model binding method above. In MVC there was the following:

base.BindModel(controllerContext, bindingContext);

This same approach does not work in WebAPI. Maybe I'm going about this wrong and there is another way to accomplish what I want so please suggest if a custom model binder is not the correct approach. What I'm trying to prevent doing is have to manipulate the posted object inside the controller. I could technically do that after it has been model bound, but I'm trying to do that earlier in the call stack so that the controller doesn't need to worry about the custom manipulation of those 2 fields.

How can I initiate default model binding against the bindingContext in my custom model binder so that I have a fully populated object where then I can just manipulate/massage the last 2 fields I need before returning?

like image 293
atconway Avatar asked Apr 08 '16 16:04

atconway


People also ask

What is difference between FromQuery and FromBody?

[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.

How do we do parameter binding in Web API?

When Web API calls a method on a controller, it must set values for the parameters, a process called binding. By default, Web API uses the following rules to bind parameters: If the parameter is a "simple" type, Web API tries to get the value from the URI.

Which of the following is a valid default rule for parameter binding in Web API?

Default Parameter Binding in ASP.NET Web API By default, if the parameter type is of the primitive type such as int, bool, double, string, GUID, DateTime, decimal, or any other type that can be converted from the string type then Web API Framework sets the action method parameter value from the query string.

How do I use FromUri in Web API?

So, if you want to override the above default behaviour and force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter. To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter.


1 Answers

In WebApi the 'default' model binder is CompositeModelBinder which wraps all registered model binders. If you want to re-use it's functionality you could do something like:

public class MyModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType != typeof(MyModel)) return false;

        //this is the default webapi model binder provider
        var provider = new CompositeModelBinderProvider(actionContext.ControllerContext.Configuration.Services.GetModelBinderProviders());
        //the default webapi model binder
        var binder = provider.GetBinder(actionContext.ControllerContext.Configuration, typeof(MyModel));

        //let the default binder do it's thing
        var result = binder.BindModel(actionContext, bindingContext);
        if (result == false) return false;

        //TODO: continue with your own binding logic....
    }
}
like image 199
Shazwazza Avatar answered Sep 21 '22 17:09

Shazwazza