ASP.NET WebAPI 2中复杂类型的选择性自定义参数绑定

时间:2018-01-16 06:07:24

标签: asp.net asp.net-web-api2 model-binding

好的,所以在挖掘SO和其他资源后,我无法找到符合我要求的正确解决方案。

我们说我有这样一个复杂的类型:

public class CreateItemRequest : AuthenticatedRequest
{
    public Item Item { get; set; }
}

public abstract class AuthenticatedRequest
{
    public string AuthToken { get; set; }
}

这是一个控制器动作:

[HttpPost]
[Route("")]
public IHttpActionResult CreateItem(CreateItemRequest request)
{
   _aCoolInjectedBusinessLayer.CreateItem(request);
}

我只需要从自定义标头请求中对属性AuthToken进行自定义参数绑定。继承中的所有其他属性应由默认的ASP.NET模型绑定器填充。

如果我使用IModelBinder方法,则无法选择性地填充某些属性。它全有或全无。

1 个答案:

答案 0 :(得分:0)

通过HttpParameterBinding的自定义实现,您可以实现所需。它将基于默认实现来执行所有绑定,但还会检查自定义标头并填充AuthToken属性。这是工作实施:

public class AuthRequestBinding : HttpParameterBinding
{
    private readonly HttpParameterDescriptor paramDescriptor;

    public AuthRequestBinding(HttpParameterDescriptor descriptor) : base(descriptor)
    {
        paramDescriptor = descriptor;
    }

    public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
        CancellationToken cancellationToken)
    {
        var defaultBinder = new FromBodyAttribute().GetBinding(paramDescriptor);
        await defaultBinder.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);

        AuthenticatedRequest authRequest = actionContext.ActionArguments[paramDescriptor.ParameterName] as AuthenticatedRequest;
        if (authRequest != null)
        {
            IEnumerable<string> headerValues;
            if (actionContext.Request.Headers.TryGetValues("Your-Custom-Header-Here", out headerValues))
            {
                authRequest.AuthToken = headerValues.FirstOrDefault();
            }
        }
    }
}

不要忘记在Web API配置中注册自定义绑定器:

config.ParameterBindingRules.Insert(0, paramDesc =>
{
    if (typeof(AuthenticatedRequest).IsAssignableFrom(paramDesc.ParameterType))
    {
        return new AuthRequestBinding(paramDesc);
    }

    return null;
});