WebAPI ModelBinder Error
Asked Answered
W

2

10

I've implemented a ModelBinder but it's BindModel() method is not being called, and I get Error Code 500 with the following message:

Error:

Could not create a 'IModelBinder' from 'MyModelBinder'. Please ensure it derives from 'IModelBinder' and has a public parameterless constructor.

I do derive from IModelBinder and do have public parameterless constructor.

My ModelBinder Code:

public class MyModelBinder : IModelBinder
    {
        public MyModelBinder()
        {

        }
        public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            // Implementation
        }
    }

Added in Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    ModelBinders.Binders.DefaultBinder = new MyModelBinder();

    // ...
}

WebAPI Action Signature:

    [ActionName("register")]
    public HttpResponseMessage PostRegister([ModelBinder(BinderType = typeof(MyModelBinder))]User user)
    {
        return new HttpResponseMessage(HttpStatusCode.OK);
    }

User Class:

public class User
{
    public List<Communication> Communications { get; set; }
}
Wiseacre answered 28/9, 2013 at 19:29 Comment(1)
F
22

ASP.NET Web API uses a completely different ModelBinding insfracture than APS.NET MVC.

You are trying to implement the MVC's model binder interface System.Web.Mvc.IModelBinder but to work with Web API you need to implement System.Web.Http.ModelBinding.IModelBinder

So your implementation should look like this:

public class MyModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
    public MyModelBinder()
    {

    }

    public bool BindModel(
        System.Web.Http.Controllers.HttpActionContext actionContext, 
        System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
    {
        // Implementation
    }
}

For further reading:

Forelimb answered 28/9, 2013 at 19:45 Comment(4)
Thanks! it solved it, but now I can't use the DefaultModelBinder, and therefore I can't downgrade the binding to the default binder by calling base.BindModel(). I have User Model which have List<Connection>, and then it fails since the User is not of type(Connection). you have any idea?Wiseacre
ModelBinders are working quite differently in web.api. So in web.api there is no DefaultModelBinder... and usually when using web.api there are other ways exist to solve this kind of problems so you should start with the linked articles...Forelimb
thanks, I am reading these articles. Feeling a bit weird that in order to use the default implementation I need make ton of logic using the built-in MediaFormatters and/or ComplexModelBinder.Wiseacre
This was lifesaver. Why wouldn't they just call it differently? or at least the namespace to be more insightful... thanks!Matilda
P
1

This for using System.Web.ModelBinding

 using System.Web.ModelBinding;
class clsUserRegModelBinder : IModelBinder
{
   public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
   {
        throw new NotImplementedException();
   }
}

This for System.Web.MVC

using System.Web.Mvc;


class clsUserRegModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,     ModelBindingContext bindingContext)
    {
        throw new NotImplementedException();
    }
}

Note the Different i hope it help you

Posy answered 28/1, 2016 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.