You can define your own DefaultActionValueBinder. Then you can mix and match from body and uri. Here is a blog post with an example of an MvcActionValueBinder for Web Api. Making your own DefaultActionValueBinderis a preferred solution because it guarantees the binder will have finished before any other ActionFilterAttribute are executed.
I had some trouble with the implementation in the blog post and trying to get it to use my custom media formatters. Luckily all my request objects extend from a base class of Request so I made my own formatter.
in WebApiConfig
config.ParameterBindingRules.Insert(0, descriptor => descriptor.ParameterType.IsSubclassOf(typeof (Request)) ? new BodyAndUriParameterBinding(descriptor) : null);
BodyAndUriParameterBinding.cs
public class BodyAndUriParameterBinding : HttpParameterBinding
{
private IEnumerable Formatters { get; set; }
private IBodyModelValidator BodyModelValidator { get; set; }
public BodyAndUriParameterBinding(HttpParameterDescriptor descriptor)
: base (descriptor)
{
var httpConfiguration = descriptor.Configuration;
Formatters = httpConfiguration.Formatters;
BodyModelValidator = httpConfiguration.Services.GetBodyModelValidator();
}
private Task
Request.cs
public abstract class Request : IValidatableObject
{
public virtual IEnumerable Validate(ValidationContext validationContext)
{
yield return ValidationResult.Success;
}
}