After reading this blog post on how to return HTML from Web API 2 using IHttpActionResult
, I wanted to somehow "wire-up" this IHttpActionResult
to my ApiController
based on the Accept
header that is sent with request.
Given controller actions that have signature similar to this:
public MyObject Get(int id)
{
return new MyObject();
}
If the request specifies the Accept: text/html
, this IHttpActionResult
should be used to return HTML. Is that possible? In addition, some insight on how this content negotiation pipeline works for json or xml (that have built-in support) would be greatly appreciated.
If we keep the discussion of IHttpActionResult
aside for a momment, Content-negotiation process in Web API is driven through formatters. So you would need to create a new formatter for handling the media type text/html
.
Web API exposes the default algorithm it uses for content-negotiation called DefaultContentNegotiator
which is an implementation of the service IContentNegotiator
.
Now this negotiation algorithm can be run either by Web API automatically for you like in the following cases:
Usage # 1:
public MyObject Get(int id)
{
return new MyObject();
}
OR
you can manually run the negotiation yourself like in the following:
Usage #2 :
public HttpResponseMessage Get()
{
HttpResponseMessage response = new HttpResponseMessage();
IContentNegotiator defaultNegotiator = this.Configuration.Services.GetContentNegotiator();
ContentNegotiationResult negotationResult = defaultNegotiator.Negotiate(typeof(string), this.Request, this.Configuration.Formatters);
response.Content = new ObjectContent<string>("Hello", negotationResult.Formatter, negotationResult.MediaType);
return response;
}
Regarding IHttpActionResults:
In the following scenario, Ok<>
is a shortcut method for generating an instance of type
OkNegotiatedContentResult<>
.
public IHttpActionResult Get()
{
return Ok<string>("Hello");
}
The thing is this OkNegotiatedContentResult<>
type does similar thing as in Usage # 2 scenario above. i.e they run the negotiator internally.
So to conclude, if you plan to support text/html
media type then you need to write a custom formatter and add it to Web API's formatter collection and then when you use Ok<string>("Hello")
with an Accept header of text/html
, you should see the response in text/html
. Hope this helps.