Feb 17, 2012 at 11:20 AM
Edited Feb 17, 2012 at 3:42 PM
Please can someone let me know how to add a custom model binder? I'm after some way of transforming different input representations to a common type (similar to the string->Geopoint) demo in the preview. Previously I was using an HttpOperationHandler.
For example, MVC has the following but that takes an System.Web.Mvc.IModelBinder not an System.Web.Http.ModelBinding.IModelBinder:
What I've tried
I've seen I could potentially use a custom DependencyResolver to provide a custom ModelBinderProvider, from that I could then return a custom model binder. However I'm sure there must be a simpler way. What implementation of IModelBinder should I be deriving
from in order to get default behaviour?
Also if I try and read the body of the content in my custom model binder it comes out blank (the headers are available and look ok but doing say actionContext.Request.Content.ReadAsStringAsync().Result is empty - perhaps something has already read the content?
I've noticed actionContext.RequestContentKeyValueModel already seems to know what's in the content so perhaps I'm too late.
There is also a CustomModelBinderAttribute that I could derive from and apply my parameters(?) - am just trying that now to see if I can access headers.
I've also looked into creating a custom HttpActionDescriptor mostly to transform the return value. This adapts the default ActionDescriptor and overrides the execute so that I can transform the return value which seems to work. I don't think I can do anything
for the request in here though. I've created a custom ApiControllerActionInvoker in order to wrap the actionContext.ActionDescriptor property.
- I would like my model binder to be able to switch based on values in the request header in order to support versioning. e.g. if v1 in header and destination type is BookModel then use v1BookTransform otherwise use v2BookTransform.
- Keep as much out of the box hook-points and functionality as possible (i.e. I'd rather replace a small bit rather than end up plugging in a replacement that means we need to re-implement a load of lost functionality like executing MediaTypeFormatters).