【问题标题】:.NET HttpWebRequest & SendChunked: how to send a large content?.NET HttpWebRequest & SendChunked:如何发送大量内容?
【发布时间】:2012-09-17 10:20:30
【问题描述】:

我正在编写一个控制台应用程序,它必须通过 Web 服务发送数据来将大型 SQL 表从一个数据库复制到另一个数据库。因为表可能非常大,而且它们不能(也不应该)完全存储在内存中,所以我使用 DataReader 顺序读取数据并希望将其流式传输到 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

我的问题是网络服务只接收第一块数据,例如如果 CHUNK_ROWS_COUNT = 5 那么它只接收 5 行数据。 (我知道这不是 HttpWebRequest 将产生的块的大小)。

我唯一的猜测是我通过流发送了许多序列化数据包,每个数据包都由一些序列化标头封装,因此 Web 服务中的反序列化过程只会找到并解封装第一个,但这只是一个想法,我不确定如何以不同的方式做到这一点。我无法序列化整个内容并分块发送写入,因为整个内容不适合内存。

有什么建议吗?

提前非常感谢

【问题讨论】:

    标签: .net stream httpwebrequest chunks


    【解决方案1】:

    我不确定您是否可以在 WCF 中使用手动 HttpWebRequest 执行此操作。 WCF 将自己处理块,不要重新发明轮子。

    一些很棒的文章:

    不要忘记在 wcf 配置中更改阅读器配额

    【讨论】:

    • 我知道 WCF 应该通过在 WebRequest 中将 SendChunked 设置为 true 来处理块,但我不知道如何发送大型序列化数据(数据足够大以至于它不能全部放入内存,因此不能一口气连载)。我想知道我做得对还是必须做不同的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    相关资源
    最近更新 更多