2013-12-16 42 views
6

我已經做了一些搜索但似乎無法找到任何東西...的WebAPI:映射參數標頭值

使用的WebAPI,我想輸入參數映射到一個標頭值:例如

E.g.在控制器:

public User GetUser(int id){ 
    ... 
    return user; 
} 

我想的WebAPI映射id參數到一個首標值(例如X-AUTH:1234)...而不是URL參數。

這是支持嗎?

回答

24

我不認爲這是支持開箱即用的,例如像與[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

這正是我所期待的。謝謝。 –

+0

[FromHeader(「MyHeader」)]是否也適用於您的代碼? –

3

謝謝菲利波夫的答案..我把你的代碼,並修改了一下,以滿足我的需求。我在這裏發佈我的更改以防萬一任何人可以使用這個。

我做了2個變化。

  1. 我喜歡FromHeaderAttribute的想法,但沒有子類。我公開這個類,並要求用戶設置參數名稱。

  2. 我需要支持除字符串以外的其他數據類型。所以我試圖將字符串值轉換爲描述符的parameterType。

使用方法如下:

[HttpGet] 
public void DeleteWidget(long widgetId, [FromHeader("widgetVersion")] int version) 
{ 
    ... 
} 

這是我FromHeaderBinding上DOTNET的核心

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; 
    } 
} 
+1

對於使用Swashbuckle/Swagger的實現也很有用:http://analogcoder.com/2015/11/how-to-create-header-using-swashbuckle/ – OzBob

2

的WebAPI已經具有用於從請求中提取數據的一些附加屬性。 Microsoft.AspNetCore.Mvc.FromHeaderAttribute將從請求頭中讀取。

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