Just getting all my ducks in a row so I can migrate from WCF to ASP.NET. One thing I'm not sure about is the following...
In my WCF preview 6 service, I have a message handler that gets the user's creds from the request, authenticates, and reads data about the user from the database. It then news-up and populates a
User object which it adds to the request's properties. Then a very simple operation handler takes the
User object and exposes it such that all my operation methods (soon to be controller actions) take the
User object as their first argument.
How would I replace this operation handler in ASP.NET Web API? If you can give a simple code example, that would be great. Thanks.
public class CustomModelBinderProvider : ModelBinderProvider
{
CustomModelBinder cmb = new CustomModelBinder();
public CustomModelBinderProvider()
{
//Console.WriteLine("In CustomModelBinderProvider ctr");
}
public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(User))
{
return cmb;
}
return null;
}
}
public class CustomModelBinder : IModelBinder
{
public CustomModelBinder()
{
//Console.WriteLine("In CustomModelBinder ctr");
}
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
//Console.WriteLine("In BindModel");
bindingContext.Model = new User() { Id = 2, Name = "foo" };
return true;
}
}
Configuring the custom ModelBinder for the whole service
IEnumerable<object> modelBinderProviderServices = config.ServiceResolver.GetServices(typeof(ModelBinderProvider));
List<Object> services = new List<object>(modelBinderProviderServices);
services.Add(new CustomModelBinderProvider());
config.ServiceResolver.SetServices(typeof(ModelBinderProvider), services.ToArray());
Configuring for specific action method
public HttpResponseMessage<Contact> Get([ModelBinder(typeof(CustomModelBinderProvider))] User user)
Thanks for all the replies. I can indeed access the request properties via the base controller, but it would be cooler to implement dravva's custom model binder, and that way I can preserve my current method signatures, which loads of unit tests expect.
I'll give it a go when I migrate on Monday. Funny, I've been using MVC for years, but never had to dive into the model binding mechanism.
public class CustomModelBinderProvider : ModelBinderProvider
{ etc.
Thanks dravva. This has worked out very well. I applied my custom model binder to the whole service. Never would have figured how to do that on my own.
awebb
Member
204 Points
91 Posts
How to replace my old operation handler...
Feb 25, 2012 10:13 AM|LINK
Just getting all my ducks in a row so I can migrate from WCF to ASP.NET. One thing I'm not sure about is the following...
In my WCF preview 6 service, I have a message handler that gets the user's creds from the request, authenticates, and reads data about the user from the database. It then news-up and populates a User object which it adds to the request's properties. Then a very simple operation handler takes the User object and exposes it such that all my operation methods (soon to be controller actions) take the User object as their first argument.
How would I replace this operation handler in ASP.NET Web API? If you can give a simple code example, that would be great. Thanks.
dravva
Member
142 Points
31 Posts
Microsoft
Re: How to replace my old operation handler...
Feb 25, 2012 11:03 AM|LINK
dravva
Member
142 Points
31 Posts
Microsoft
Re: How to replace my old operation handler...
Feb 25, 2012 11:59 AM|LINK
public class CustomModelBinderProvider : ModelBinderProvider { CustomModelBinder cmb = new CustomModelBinder(); public CustomModelBinderProvider() { //Console.WriteLine("In CustomModelBinderProvider ctr"); } public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(User)) { return cmb; } return null; } } public class CustomModelBinder : IModelBinder { public CustomModelBinder() { //Console.WriteLine("In CustomModelBinder ctr"); } public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { //Console.WriteLine("In BindModel"); bindingContext.Model = new User() { Id = 2, Name = "foo" }; return true; } } Configuring the custom ModelBinder for the whole service IEnumerable<object> modelBinderProviderServices = config.ServiceResolver.GetServices(typeof(ModelBinderProvider)); List<Object> services = new List<object>(modelBinderProviderServices); services.Add(new CustomModelBinderProvider()); config.ServiceResolver.SetServices(typeof(ModelBinderProvider), services.ToArray()); Configuring for specific action method public HttpResponseMessage<Contact> Get([ModelBinder(typeof(CustomModelBinderProvider))] User user)SixiS
Member
50 Points
16 Posts
Re: How to replace my old operation handler...
Feb 25, 2012 12:29 PM|LINK
You can write a custom HttpModule (IHttpModule) to authenticate the user.
SiggiGG
Member
265 Points
105 Posts
Re: How to replace my old operation handler...
Feb 25, 2012 11:12 PM|LINK
Instead of adding the user as a parameter to all your API methods, you can access request properties via the base ApiController class now.
awebb
Member
204 Points
91 Posts
Re: How to replace my old operation handler...
Feb 26, 2012 07:14 AM|LINK
Thanks for all the replies. I can indeed access the request properties via the base controller, but it would be cooler to implement dravva's custom model binder, and that way I can preserve my current method signatures, which loads of unit tests expect. I'll give it a go when I migrate on Monday. Funny, I've been using MVC for years, but never had to dive into the model binding mechanism.
awebb
Member
204 Points
91 Posts
Re: How to replace my old operation handler...
Feb 27, 2012 01:43 PM|LINK
public class CustomModelBinderProvider : ModelBinderProvider { etc.Thanks dravva. This has worked out very well. I applied my custom model binder to the whole service. Never would have figured how to do that on my own.
Noel Abraham...
Member
6 Points
18 Posts
Re: How to replace my old operation handler...
May 20, 2012 06:41 PM|LINK
Crumbs! We used to be able to do only this in MVC:
Perhaps the Web API must (should!) have something similar?
awebb
Member
204 Points
91 Posts
Re: How to replace my old operation handler...
Sep 01, 2012 07:35 AM|LINK
Updating to ASP.NET Web API full release yesterday, I note that dravva's solution doesn't work anymore. So I've unmarked it as the answer.
After considering a few options, I ended up doing this for every controller action that takes a "User" instance:-
void MyAction([ModelBinder(UserModelBinder)] User user) { ... }I got rid of the custom model binder provider class; no longer needed.
But perhaps there's a cleaner way?
Kiran Challa
Participant
1442 Points
281 Posts
Microsoft
Re: How to replace my old operation handler...
Sep 03, 2012 06:58 PM|LINK
You can register the modelbinder of User on the config: config.BindParameter(typeof(User), new UserModelBinder());
----
You could also use HttpParameterBinding for your scenario here. Following blog posts have more details:
http://blogs.msdn.com/b/jmstall/archive/2012/05/11/webapi-parameter-binding-under-the-hood.aspx
http://blogs.msdn.com/b/hongmeig1/archive/2012/05/11/how-to-write-a-custom-parameter-binding-to-construct-an-object-either-from-body-or-from-uri-s-query.aspx
Kiran Challa