调用另一个流内容web api方法的Web api方法?

问题描述:

这是我的情况我有两个web api服务。第一种方法有处理一些数据的方法,当部分数据准备就绪时,它将其推送到流中。调用另一个流内容web api方法的Web api方法?

public HttpResponseMessage Get() 
     { 
      var response = Request.CreateResponse(); 
      response.Content = new PushStreamContent(WriteToStream); 
      return response; 
     } 

     public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) 
     { 
      ....... 
     } 

第二个web api在调用第一个web api的控制器中有一个方法。它必须读取的部分从流用它做的东西,把我给它自己的流:

public HttpResponseMessage Get() 
     { 
      Stream stream = null; 

      using(HttpClient httpClient = new HttpClient()) 
      { 
       httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite); 
       HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/fistWebApi/"); 

       var response = httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead); 

       var content = response.Result.Content.ReadAsStreamAsync(); 

       stream = content.Result; 
      } 

      var msg = Request.CreateResponse(); 

      msg.Content = new PushStreamContent(WriteToStream); 

      return msg; 
     } 
public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) 
      { 
       ....... 
      } 

的问题是,我不知道如何调用SendAsyncReadAsStreamAsync同步。现在它不会等待,并且stream在尝试使用时未正确初始化。我希望第二个方法的代码等待,直到第一个方法将部分数据放到流中。我尝试使用ContinueWith,但后来我无法做到。我知道这是一个模糊的解释,如果有任何问题我会试着更深入地解释。

尝试......

public HttpResponseMessage Get() 
     { 

      using (HttpClient httpClient = new HttpClient()) 
      { 
       httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite); 
       HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://www.google.ca"); 

       return httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) 
        .ContinueWith((t) => 
         { 
          return new HttpResponseMessage() 
           { 
            Content = t.Result.Content 
           }; 
         }).Result; 

      } 

     } 

上面的代码为我工作。这样做的缺点是,因为你使用了HttpCompletionOption.ResponseContentRead,所以来自远程服务的整个有效负载在返回客户端之前将被缓冲。

如果您改为使用HttpCompletionOption.ResponseHeadersReadt.Result.Content将返回网络流。这样,当您的客户端拉取响应流时,它将直接从远程资源进行流式传输。我假设你正在试图用你正在返回的PushStreamContent做什么。

+0

不应该通过将状态码传递给构造函数来转发状态码吗?即:新的HttpResponseMessage(t.result.StatusCode) – 2015-05-21 01:25:22

+2

@eventualEntropy是的。并复制标题。并通过使方法异步来摆脱那些讨厌的.Result调用。该代码有太多的错误。 – 2015-05-21 02:24:07

+0

很好的答案,我在两个API之间构建了一种“代理”,我正努力寻找一种方法来流式处理大文件而不缓冲RAM中的整个文件,这就是解决方案!我发现一个重要的注意事项:如果您在Web Api自主主机项目中使用它,请确保您还延长了HttpSelfHostConfiguration对象的超时时间,否则超过60秒的请求将失败。 – 2017-10-24 14:05:03