.NET HttpWebRequest и SendChunked: как отправить большой контент?

Я пишу консольное приложение, которое должно копировать большие таблицы SQL из одной базы данных в другую, отправляя данные через веб-службу. Поскольку таблицы могут быть очень большими и поскольку они не могут (и не должны) полностью храниться в памяти, я использую DataReader для последовательного чтения данных и надеялся передать их в веб-службу.

Для этого я объявил свой веб-сервис следующим образом:

<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).

Мое единственное предположение состоит в том, что я отправляю несколько сериализованных пакетов данных через поток, каждый из которых инкапсулирован некоторыми заголовками сериализации, и поэтому процесс десериализации в веб-службе находит и декапсулирует только первый, но это всего лишь идея, и я не уверен, как сделать это по-другому. Я не могу сериализовать весь контент и отправить его на запись по частям, потому что весь контент не помещается в памяти.

Любой совет?

Заранее большое спасибо


person Nicolas    schedule 17.09.2012    source источник


Ответы (1)


Я не уверен, что вы можете сделать это в WCF с помощью ручного HttpWebRequest. WCF будет обрабатывать фрагменты самостоятельно, не изобретайте велосипед.

несколько замечательных статей:

Не забудьте изменить квоты на чтение в конфиге wcf

person Cybermaxs    schedule 17.09.2012
comment
Я знаю, что WCF должен обрабатывать фрагменты, просто установив SendChunked в значение true в WebRequest, но я не уверен, как отправлять большие сериализованные данные (данные достаточно большие, чтобы они не могли поместиться все в памяти и, следовательно, не могут быть сериализованы за один раз ). Я хотел бы знать, правильно ли я делаю это или нужно сделать по-другому. - person Nicolas; 17.09.2012