2013-12-16 8 views
6

をヘッダにマッピングパラメータ... WEBAPIを使用してWEBAPI:私はいくつかの検索を行ってきたが、何かを見つけるように見えるしていない値

、私は、ヘッダの値に入力パラメータをマップしたいと思います。例えば

など。 inコントローラ:

URLパラメータではなく、WebApiでidパラメータをヘッダー値(X-Auth:1234など)にマッピングします。

これはサポートされていますか?

答えて

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) 
{ 
    ... 
} 

およびDOTNET Coreでこの私の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; 
    } 
} 
+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 
} 
関連する問題