2017-06-02 84 views
0

我需要流大對象。我無法弄清楚如何分塊發送。發佈的代碼工作,但是,stream.Flush()只被調用一次。所以,基本上我是緩衝對象 - 不好。我如何撥打stream.Flush()多次?如果我有一個集合,我可以在一個循環中流/沖洗。那麼如何用大對象來做到這一點?流Json - PushStreamContent與大對象

服務器代碼:

public async Task<HttpResponseMessage> ConvertToTiffAsync([FromBody] DocumentDto dto) 
       { 
        // THIS IS LARGE 
        var document = await _service.ConvertToTiffAsync(dto); 
        var response = Request.CreateResponse(); 
        response.Content = new PushStreamContent((stream, content, context) => 
        { 
         var serializer = new JsonSerializer(); 
         using (var writer = new StreamWriter(stream)) 
         { 
          using (var jsonTextWriter = new JsonTextWriter(writer)) 
          { 
           serializer.Serialize(jsonTextWriter, document); 
           stream.Flush(); // ONLY CALLED ONCE - NEED MANY CALLS 
          } 
         } 
        }); 
        return response; 
       } 

客戶端代碼(流在這裏沒有發生,但需要):

using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true })) 
      { 
       client.Timeout = new TimeSpan(0, 5, 0); 
       var stringContent = new StringContent(JsonConvert.SerializeObject(dto), Encoding.UTF8, "application/json"); 
       using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, endpoint)) 
       { 
        httpRequest.Content = stringContent; 
        using (HttpResponseMessage response = await client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) 
        { 
         response.EnsureSuccessStatusCode(); 
         using (var streamReader = new StreamReader(await response.Content.ReadAsStreamAsync())) 
         using (var jsonReader = new JsonTextReader(streamReader)) 
         { 
          var serializer = new JsonSerializer(); 
          return await Task.Run(() => serializer.Deserialize<ConvertDocumentDto>(jsonReader)).ConfigureAwait(false); 
         } 
        } 
       } 
      } 
+0

你不需要刷新。 PushStreamContent所做的基本上是將所有寫入它的數據直接傳輸到客戶端而不緩衝內容。那麼你確定完整的JSON表示在內存中嗎? – ckuri

+0

也根據https://www.thomaslevesque.com/2013/11/30/uploading-data-with-httpclient-using-a-push-model/如果你想流JSON,而不是PushStreamContent你可以只是使用新的ObjectContent(文檔,新的JsonMediaTypeFormatter()),它應該做同樣的事情,但要簡潔得多。 – ckuri

+0

@ckuri ...該文章專注於上傳不下載。另外,我不相信直到調用flush()之前數據纔會流式傳輸 - 至少這是我在運行代碼時看到它的方式。 –

回答

0

您的服務器的代碼似乎是罰款。但是,您的客戶端代碼似乎無法與服務器正確交互。

如果要設置DocumentDto輸入,則需要將JSON寫入請求,而不是響應。如果你想在內存中沒有完整的JSON的情況下使用服務器動作,你需要一個JsonTextReader。所以一般在客戶端應該是:

如果你的DTO是小,你不介意在內存中,而不是client.PostAsync(URL)完整的JSON,你也可以使用client.PostAsJsonAsync (url,dto),如果您導入System.Net.Http.Formatting.dll,它位於HttpClientExtensions名稱空間中。

+0

對不起,但我發佈了錯誤的客戶端代碼。現在的實際代碼ID並不流式傳輸。 –