【问题标题】:How IIS/Owin converts IHttpActionResult to application/json down the pipeline?IIS/Owin 如何在管道中将 IHttpActionResult 转换为 application/json?
【发布时间】:2018-02-12 07:32:19
【问题描述】:

我正在探索 IIS/Owin 管道的工作原理。我试图在管道中找到 IIS/Owin 使用的库/方法,以将 IHttpActionResult(从控制器返回)转换为正确的内容类型,如请求中存在的 application/json。

控制器 -

[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() }
    });
}

API 使用者收到的数据 -

[
    {
        "code": "prod101",
        "title": "LAPTOP"
    },
    {
        "code": "prod102",
        "title": "MOBILE"
    }
]

从 IHttpActionResult 到 application/json 的转换何时发生?

【问题讨论】:

    标签: c# asp.net iis-7 asp.net-web-api2 owin


    【解决方案1】:

    IHttpActionResult 有一个方法 ExecuteAsync,它返回 HttpResponseMessage

    public interface IHttpActionResult
    {
        Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
    }
    

    当您在控制器中使用Json() 时,它将创建一个新的JsonResult(link)

    这是创建 HttpResponseMessage 的方法,它是一个 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;
        }
    

    Owin 中有一个HttpMessageHandlerAdapter 类,它有一个SendResponseMessageAsync 方法将HttpResponseMessage 返回给客户端。这是来自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);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-05
      • 1970-01-01
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      • 2016-12-22
      • 1970-01-01
      相关资源
      最近更新 更多