我正在編寫一個控制檯應用程序,它必須通過發送數據通過Web服務將大型SQL表從數據庫複製到另一個數據庫。由於這些表格可能非常大,並且因爲它們不能(也不應該)完全存儲在內存中,所以我使用DataReader來順序讀取數據,並希望將其傳輸到Web服務。.NET HttpWebRequest&SendChunked:如何發送大內容?
爲了做到這一點,我有我的web服務聲明,如下所示:
<OperationContract()>
<WebInvoke(UriTemplate:="{Id}/SendData", method:="PUT", BodyStyle:=WebMessageBodyStyle.WrappedRequest)>
Sub UploadData(ByVal Id As String, ByVal DataStream As Stream)
在我的控制檯應用程序,我創建像這樣的請求:
Dim tRequest As HttpWebRequest = HttpWebRequest.Create(URL_WEBSERVICES & "DataLoad/" & _Id & "/SendData")
tRequest.SendChunked = True
tRequest.Method = "PUT"
tRequest.ContentType = "application/octet-stream"
然後我打開請求流和寫入數據如下:
While tSqlReader.Read
' Check if a new chunk of data must be created
If tRows Is Nothing Then
tRows = New List(Of Object)
End If
' Fill chunk with data
tRowValues = New Object(tSqlReader.FieldCount - 1) {}
tSqlReader.GetValues(tRowValues)
tRows.Add(tRowValues)
' Check if chunk is full and must be sent
If tRows.Count = CHUNK_ROWS_COUNT Then
' Write data to the request stream
tDataChunk = SerializeToByteArray(tRows)
tStream.Write(tDataChunk, 0, tDataChunk.Length)
tRows = Nothing
tDataChunk = Nothing
End If
End While
' Write final data to the request stream
If tRows IsNot Nothing Then
tDataChunk = SerializeToByteArray(tRows)
tStream.Write(tDataChunk, 0, tDataChunk.Length)
End If
然後我關閉請求流並調用tRequest.GetResponse()。
SerializeToByArray是下列的函數:
Private Function SerializeToByteArray(ByVal pObject As Object) As Byte()
If pObject Is Nothing Then Return Nothing
Dim tBinaryFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim tMemoryStream As New MemoryStream()
tBinaryFormatter.Serialize(tMemoryStream, pObject)
Return tMemoryStream.ToArray
End Function
我的問題是Web服務只接收數據,例如第一數據塊如果CHUNK_ROWS_COUNT = 5,那麼它只接收5行數據。 (我知道這不是HttpWebRequest將做的塊的大小)。
我唯一的猜測就是我通過流發送了大量的序列化數據包,每個數據包都由一些序列化頭封裝,因此Web服務中的反序列化過程只發現並解封第一個,但這只是一個想法,我不知道如何做不同。我無法序列化整個內容併發送分塊,因爲整個內容不適合內存。
有什麼建議嗎?
感謝很多提前
我知道WCF應處理塊只是通過設置SendChunked爲真在WebRequest中,但我不知道如何發送大型序列化數據(數據量足夠大,以至於無法將所有數據都放入內存中,因此不能一次執行)。我想知道我是否做得對,或者如果做得不一樣。 – Nicolas