我做了一些搜索,但似乎没有找到任何东西......
使用WebApi,我想将输入参数映射到标题值:例如
E.g。在控制器中:
public User GetUser(int id){
...
return user;
}
我希望WebApi将id参数映射到标头值(例如X-Auth:1234)...而不是URL参数。
支持吗?
答案 0 :(得分:30)
我不认为这是开箱即用的,例如[FromBody]属性。 您似乎应该能够使用模型绑定器来实现此功能,如here所述。在模型绑定器中,您可以访问请求及其标头,因此您应该能够读取标头并将其值设置为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")
{
}
}
然后你可以像这样使用它:
[HttpGet]
public IHttpActionResult GetItem([MyHeader] string headerValue)
{
...
}
希望有所帮助。
答案 1 :(得分:8)
DotNet Core上的WebApi具有一些用于从请求中提取数据的附加属性。 Microsoft.AspNetCore.Mvc.FromHeaderAttribute 将从请求头中读取。
public ActionResult ReadFromHeader([FromHeader(Name = "your-header-property-name")] string data){
//Do something
}
答案 2 :(得分:5)
谢谢filipov的回答..我拿了你的代码并修改了一下以满足我的需要。我在这里发布我的更改,以防任何人都可以使用它。
我做了2次更改。
我喜欢FromHeaderAttribute的想法,但没有子类化。我公开了这个类,并要求用户设置param名称。
我需要支持除字符串之外的其他数据类型。所以我尝试将字符串值转换为描述符的parameterType。
像这样使用:
[HttpGet]
public void DeleteWidget(long widgetId, [FromHeader("widgetVersion")] int version)
{
...
}
这是我的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;
}
}