您可以通过自定义实现 HttpParameterBinding 来实现您的目标。这是这种活页夹的工作示例:
public class UriOrBodyParameterBinding : HttpParameterBinding
{
private readonly HttpParameterDescriptor paramDescriptor;
public UriOrBodyParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor)
{
paramDescriptor = descriptor;
}
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
CancellationToken cancellationToken)
{
HttpParameterBinding binding = actionContext.Request.Content.Headers.ContentLength > 0
? new FromBodyAttribute().GetBinding(paramDescriptor)
: new FromUriAttribute().GetBinding(paramDescriptor);
await binding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
}
}
我们检查Content-Length HTTP header 来判断请求是否包含http body。如果是,我们从主体绑定模型。否则模型是从 Url 绑定的。
您还应该添加自定义属性来标记将使用此自定义绑定器的操作参数:
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class FromUriOrBodyAttribute : Attribute
{
}
这里是应添加到WebApiConfig.Register() 方法的活页夹注册。我们检查动作参数是否标记为FromUriOrBodyAttribute,并在这种情况下使用我们的自定义绑定器:
config.ParameterBindingRules.Insert(0, paramDesc =>
{
if (paramDesc.GetCustomAttributes<FromUriOrBodyAttribute>().Any())
{
return new UriOrBodyParameterBinding(paramDesc);
}
return null;
});
现在您可以使用一个 Post 操作来绑定来自请求正文或 Url 的模型:
[HttpPost]
public void Post([FromUriOrBody] Data data)
{
// ...
}