Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set custom headers when using IHttpActionResult?

In ASP.NET Web API 2, the IHttpActionResult offers a lot of value in simplifying controller code and I'm reluctant to stop using it, but I've hit a problem.

I need to set an ETag on an outgoing response, and I cannot find any property which gives me access to the response's headers. At the moment I'm using the Ok<T>(T content) helper method from the ApiController, which returns an OkNegotiatedContentResult<T> object. That doesn't seem to have anything exposed which would let me modify the headers though.

Am I missing something, or is there really no way to do this while using the stock IHttpActionResult types? I considered a message handler, but then I'd have to figure out how to pass the ETag out of the action (the ETags are generated differently for different actions, so it's not a matter of making a generic handler for all actions).

I'd like to avoid having to use the raw HttpResponseMessage, but at the moment that's looking difficult.

like image 729
ehdv Avatar asked Jan 29 '14 19:01

ehdv


People also ask

How do I get custom header values in net core API?

Using IHTTPContextAccessor to extract custom header The above–discussed HttpContext or Request class gives us access to metadata including headers of given HttpContext within Controller. However, if you need to access headers or any HttpContext metadata in other services or modules then please use IHTTPContextAccessor.

When should I use IHttpActionResult?

IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance. If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.

What is a custom HTTP header?

Custom HTTP headers are commonly meant to provide additional information that may be pertinent to a web developer, or for troubleshooting purposes. These headers often times begin with X- , however, we'll discuss naming convention further on.


1 Answers

For your scenario, you would need to create a custom IHttpActionResult. Following is an example where I derive from OkNegotiatedContentResult<T> as it runs Content-Negotiation and sets the Ok status code.

public class CustomOkResult<T> : OkNegotiatedContentResult<T> {     public CustomOkResult(T content, ApiController controller)         : base(content, controller) { }      public CustomOkResult(T content, IContentNegotiator contentNegotiator, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)          : base(content, contentNegotiator, request, formatters) { }      public string ETagValue { get; set; }      public override async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)     {         HttpResponseMessage response = await base.ExecuteAsync(cancellationToken);          response.Headers.ETag = new EntityTagHeaderValue(this.ETagValue);          return response;     }         } 

Controller:

public class ValuesController : ApiController {     public IHttpActionResult Get()     {         return new CustomOkResult<string>(content: "Hello World!", controller: this)             {                     ETagValue = "You ETag value"             };     } } 

Note that you can also derive from NegotiatedContentResult<T>, in which case you would need to supply the StatusCode yourself. Hope this helps.

You can find the source code of OkNegotiatedContentResult<T> and NegotiatedContentResult<T>, which as you can imagine are simple actually.

like image 174
Kiran Avatar answered Sep 21 '22 20:09

Kiran