2013-04-06 44 views
2

這是我的情況我有兩個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,但後來我無法做到。我知道這是一個模糊的解釋,如果有任何問題我會試着更深入地解釋。

回答

8

嘗試......

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