WebApi:将参数映射到标头值

fri*_*gon 13 asp.net asp.net-web-api asp.net-web-api-routing

我做了一些搜索,但似乎没有找到任何东西......

使用WebApi,我想将输入参数映射到标头值:例如

例如在控制器中:

public User GetUser(int id){
   ...
   return user;
}
Run Code Online (Sandbox Code Playgroud)

我希望WebApi将id参数映射到标头值(例如X-Auth:1234)...而不是URL参数.

这支持吗?

fil*_*pov 33

我不认为这是开箱即用的,例如[FromBody]属性.看来你应该能够通过使用模型绑定来实现这一功能,如所描述这里.在模型绑定器中,您可以访问请求及其标头,因此您应该能够读取标头并将其值设置为bindingContext.Model属性.

编辑:进一步阅读文章,似乎自定义HttpParameterBinding和ParameterBindingAttribute是一个更合适的解决方案,或者至少我会这样做.您可以实现一个通用的[FromHeader]属性来完成这项工作.我也在解决同样的问题,所以一旦我有解决方案,我会发布我的解决方案.

编辑2:这是我的实现:

public class FromHeaderBinding : HttpParameterBinding
{
    private string name;

    public FromHeaderBinding(HttpParameterDescriptor parameter, string headerName) 
        : base(parameter)
    {
        if (string.IsNullOrEmpty(headerName))
        {
            throw new ArgumentNullException("headerName");
        }

        this.name = headerName;
    }

    public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        IEnumerable<string> values;
        if (actionContext.Request.Headers.TryGetValues(this.name, out values))
        {
            actionContext.ActionArguments[this.Descriptor.ParameterName] = values.FirstOrDefault();
        }

        var taskSource = new TaskCompletionSource<object>();
        taskSource.SetResult(null);
        return taskSource.Task;
    }
}

public abstract class FromHeaderAttribute : ParameterBindingAttribute
{
    private string name;

    public FromHeaderAttribute(string headerName)
    {
        this.name = headerName;
    }

    public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
    {
        return new FromHeaderBinding(parameter, this.name);
    }
}

public class MyHeaderAttribute : FromHeaderAttribute
{
    public MyHeaderAttribute()
        : base("MyHeaderName")
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

[HttpGet]
public IHttpActionResult GetItem([MyHeader] string headerValue)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.


Fri*_*der 15

DotNet Core上的WebApi具有一些用于从请求中提取数据的附加属性.Microsoft.AspNetCore.Mvc.FromHeaderAttribute将从请求头中读取.

public ActionResult ReadFromHeader([FromHeader(Name = "your-header-property-name")] string data){
   //Do something
}
Run Code Online (Sandbox Code Playgroud)


NYC*_*ris 5

谢谢filipov的回答。.我带了您的代码,并对其进行了一些修改以满足我的需要。如果有人可以使用此更改,我将在此处发布我的更改。

我进行了2次更改。

  1. 我喜欢FromHeaderAttribute的想法,但是没有子类。我将此类公开,并要求用户设置参数名称。

  2. 除了字符串,我还需要支持其他数据类型。因此,我尝试将字符串值转换为描述符的parameterType。

像这样使用它:

[HttpGet]
public void DeleteWidget(long widgetId, [FromHeader("widgetVersion")] int version)
{
    ... 
}
Run Code Online (Sandbox Code Playgroud)

这是我的FromHeaderBinding

public class FromHeaderBinding : HttpParameterBinding
{
    private readonly string _name;

    public FromHeaderBinding(HttpParameterDescriptor parameter, string headerName)
        : base(parameter)
    {
        if (string.IsNullOrEmpty(headerName)) throw new ArgumentNullException("headerName");
        _name = headerName;
    }

    public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        IEnumerable<string> values;
        if (actionContext.Request.Headers.TryGetValues(_name, out values))
        {
            var tempVal = values.FirstOrDefault();
            if (tempVal != null)
            {
                var actionValue = Convert.ChangeType(tempVal, Descriptor.ParameterType);
                actionContext.ActionArguments[Descriptor.ParameterName] = actionValue;
            }
        }

        var taskSource = new TaskCompletionSource<object>();
        taskSource.SetResult(null);
        return taskSource.Task;
    }
}
Run Code Online (Sandbox Code Playgroud)