Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebApi: mapping parameter to header value

I've done a few searches but haven't seem to find anything...

Using WebApi, I would like to map an input parameter to a header value: e.g.

E.g. in controller:

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

I want WebApi to map the id parameter to a header value (e.g. X-Auth: 1234)... rather than an URL parameter.

Is this supported?

like image 458
frigon Avatar asked Dec 16 '13 19:12

frigon


People also ask

How do I read header values in Web API?

As shown above, the header value can be easily read through the HttpContext object. Please add below generic logic to read through any of the custom headers. HttpContext will be accessible through the WebAPI pipeline and can be available through middleware (as shown in the above example) or .


2 Answers

I don't think this is supported out of the box, like for example with the [FromBody] attribute. It seems you should be able to achieve this functionality by using Model Binders, as described here. In the model binder you have access to the request and its headers, so you should be able to read the header and set its value to the bindingContext.Model property.

Edit: Reading the article further, it seems a custom HttpParameterBinding and a ParameterBindingAttribute is a more appropriate solution, or at least I would go this way. You could implement a generic [FromHeader] attribute, which does the job. I am also fighting the same problem, so I will post my solution once I have it in place.

Edit 2: Here is my implementation:

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

Then you can use it like this:

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

Hope that helps.

like image 125
filipov Avatar answered Oct 03 '22 04:10

filipov


WebApi on DotNet Core has a has some additional attributes for extracting data from the request. Microsoft.AspNetCore.Mvc.FromHeaderAttribute will read from the request head.

public ActionResult ReadFromHeader([FromHeader(Name = "your-header-property-name")] string data){
   //Do something
}
like image 34
Frison Alexander Avatar answered Oct 03 '22 03:10

Frison Alexander