How to write a custom parameter binding to construct an object either from body or from Uri's query
Mike has wrote this really good blog on writing a custom HttpParameterBinding at
https://blogs.msdn.com/b/jmstall/archive/2012/05/11/webapi-parameter-binding-under-the-hood.aspx
My blog just want to add a little bit complex example where you might want to have an action which looks like the following:
Code Snippet
- public class HomeController : ApiController
- {
- [HttpGet]
- [HttpPost]
- public HttpResponseMessage BindCustomComplexTypeFromUriOrBody(TestItem item)
- {
- return new HttpResponseMessage
- {
- Content = new StringContent(String.Format("BindCustomComplexType item.Name = {0}.", item.Name))
- };
- }
- }
- public class TestItem
- {
- public string Name { get; set; }
- }
Then the TestItem object can sometimes come from query like /?Name=Hongmei or coming from body. {Name:Hongmei}. It will be easy to write a custom parameter binding to do that.
Step 1: Write a custom FromUriOrFromBodyParameterBinding
Code Snippet
- public class FromUriOrBodyParameterBinding : HttpParameterBinding
- {
- HttpParameterBinding _defaultUriBinding;
- HttpParameterBinding _defaultFormatterBinding;
- public FromUriOrBodyParameterBinding(HttpParameterDescriptor desc)
- : base(desc)
- {
- _defaultUriBinding = new FromUriAttribute().GetBinding(desc);
- _defaultFormatterBinding = new FromBodyAttribute().GetBinding(desc);
- }
- public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
- {
- if (actionContext.Request.Content != null )
- {
- // we have something from the body, try that first
- return _defaultFormatterBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
- }
- else
- {
- // we need to read things from uri
- return _defaultUriBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
- }
- }
- }
Step 2: Wire the FromUriOrFromBodyParameterBinding to the configuration
Code Snippet
- public static HttpParameterBinding GetCustomParameterBinding(HttpParameterDescriptor descriptor)
- {
- if ( descriptor.ParameterType == typeof(TestItem))
- {
- return new FromUriOrBodyParameterBinding(descriptor);
- }
- // any other types, let the default parameter binding handle
- return null;
- }
Code Snippet
- config.ParameterBindingRules.Insert(0, GetCustomParameterBinding);
Comments
- Anonymous
September 02, 2012
Any idea how to bind a model to both Uri and Body?