2013-12-16 16 views
6

Tôi đã thực hiện một vài tìm kiếm nhưng dường như không tìm thấy bất cứ điều gì ...WebApi: tham số ánh xạ tới giá trị tiêu đề

Sử dụng WebApi, tôi muốn ánh xạ tham số đầu vào với giá trị tiêu đề: ví dụ:

Ví dụ: trong bộ điều khiển:

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

Tôi muốn WebApi ánh xạ tham số id vào giá trị tiêu đề (ví dụ: X-Auth: 1234) ... thay vì tham số URL.

Điều này có được hỗ trợ không?

Trả lời

24

Tôi không nghĩ rằng điều này được hỗ trợ ra khỏi hộp, ví dụ như với thuộc tính [FromBody]. Có vẻ như bạn sẽ có thể đạt được chức năng này bằng cách sử dụng Trình bao Model, như được mô tả here. Trong trình kết nối mô hình, bạn có quyền truy cập vào yêu cầu và các tiêu đề của nó, vì vậy bạn có thể đọc tiêu đề và đặt giá trị của nó thành thuộc tính bindingContext.Model.

Chỉnh sửa: Đọc thêm bài viết, có vẻ như một tùy chỉnh HttpParameterBinding và ParameterBindingAttribute là một giải pháp thích hợp hơn, hoặc ít nhất tôi sẽ đi theo cách này. Bạn có thể thực hiện một thuộc tính [FromHeader] chung, thực hiện công việc. Tôi cũng chiến đấu cùng một vấn đề, vì vậy tôi sẽ đăng giải pháp của mình một khi tôi có nó.

Chỉnh sửa 2: Đây là thực hiện của tôi:

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

Sau đó, bạn có thể sử dụng nó như thế này:

[HttpGet] 
public IHttpActionResult GetItem([MyHeader] string headerValue) 
{ 
    ... 
} 

Hy vọng rằng sẽ giúp.

+1

Đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn. –

+0

[WordHeader ("MyHeader")] có hoạt động với Mã của bạn không? –

3

Cảm ơn bạn filipov cho câu trả lời .. Tôi lấy mã của bạn và sửa đổi nó một chút cho phù hợp với nhu cầu của tôi. Tôi đăng những thay đổi của tôi ở đây trong trường hợp bất kỳ ai cũng có thể tận dụng điều này.

Tôi đã thực hiện 2 thay đổi.

  1. Tôi thích ý tưởng của FromHeaderAttribute, nhưng không có phân lớp phụ. Tôi đã tạo lớp này ở chế độ công khai và yêu cầu người dùng đặt tên param.

  2. Tôi cần hỗ trợ các loại dữ liệu khác ngoài chuỗi. Vì vậy, tôi cố gắng chuyển đổi giá trị chuỗi thành parameterType của descriptor.

Sử dụng nó như thế này:

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

Và đây là FromHeaderBinding tôi

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

cũng hữu ích cho việc triển khai bằng Swashbuckle/Swagger: http://analogcoder.com/2015/11/how-to-create-header-using-swashbuckle/ – OzBob

2

WebAPI trên DotNet Lõi có một có một số thuộc tính bổ sung để trích xuất dữ liệu từ các yêu cầu. Microsoft.AspNetCore.Mvc.FromHeaderAttribute sẽ đọc từ đầu yêu cầu.

public ActionResult ReadFromHeader([FromHeader(Name = "your-header-property-name")] string data){ 
    //Do something 
} 
Các vấn đề liên quan