Reputation: 141
I am exploring how IIS/Owin pipeline works. I am trying to find the library/method used by IIS/Owin down the pipeline to convert IHttpActionResult (returned from controller) into the correct content-type like application/json as present in the request.
Controller -
[Route("")]
public IHttpActionResult Get()
{
IEnumerable<Product> productList = ProductService.GetAllProducts();
if (!productList.Any())
return Ok();
return Json(productList, new JsonSerializerSettings
{
ContractResolver = new WebContractResolver(),
Converters = new List<JsonConverter> { new TrimStringDataConverter() }
});
}
Data received by API consumer -
[
{
"code": "prod101",
"title": "LAPTOP"
},
{
"code": "prod102",
"title": "MOBILE"
}
]
When this conversion from IHttpActionResult to application/json takes place ?
Upvotes: 0
Views: 259
Reputation: 15015
IHttpActionResult
has a method ExecuteAsync
which returns HttpResponseMessage
public interface IHttpActionResult
{
Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}
When you use Json()
in your controller it will create a new JsonResult
(link)
And this is the method which create a HttpResponseMessage
which is a json.(link)
public virtual Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
}
private HttpResponseMessage Execute()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
try
{
ArraySegment<byte> segment = Serialize();
response.Content = new ByteArrayContent(segment.Array, segment.Offset, segment.Count);
MediaTypeHeaderValue contentType = new MediaTypeHeaderValue("application/json");
contentType.CharSet = _encoding.WebName;
response.Content.Headers.ContentType = contentType;
response.RequestMessage = _dependencies.Request;
}
catch
{
response.Dispose();
throw;
}
return response;
}
in Owin
there is a HttpMessageHandlerAdapter
class which has a SendResponseMessageAsync
method that return HttpResponseMessage
to client. Here's the source from github: HttpMessageHandlerAdapter
private Task SendResponseMessageAsync(HttpRequestMessage request, HttpResponseMessage response,
IOwinResponse owinResponse, CancellationToken cancellationToken)
{
owinResponse.StatusCode = (int)response.StatusCode;
owinResponse.ReasonPhrase = response.ReasonPhrase;
// Copy non-content headers
IDictionary<string, string[]> responseHeaders = owinResponse.Headers;
foreach (KeyValuePair<string, IEnumerable<string>> header in response.Headers)
{
responseHeaders[header.Key] = header.Value.AsArray();
}
HttpContent responseContent = response.Content;
if (responseContent == null)
{
SetHeadersForEmptyResponse(responseHeaders);
return TaskHelpers.Completed();
}
else
{
// Copy content headers
foreach (KeyValuePair<string, IEnumerable<string>> contentHeader in responseContent.Headers)
{
responseHeaders[contentHeader.Key] = contentHeader.Value.AsArray();
}
// Copy body
return SendResponseContentAsync(request, response, owinResponse, cancellationToken);
}
}
Upvotes: 2