Public Sub SendFile(ByVal filename As String)
coRequest = CType(WebRequest.Create(sURL), HttpWebRequest)
coRequest.ProtocolVersion = TransferHttpVersion
coRequest.Method = "POST"
coRequest.ContentType = "multipart/form-data; boundary=" & BeginBoundary
coRequest.Headers.Add("Cache-Control", "no-cache")
coRequest.KeepAlive = True
Dim strFields As String = GetFormfields()
Dim strFileHdr As String = GetFileheader(filename)
Dim strFileTlr As String = GetFiletrailer()
Dim info As FileInfo = New FileInfo(filename)
coRequest.ContentLength = strFields.Length + strFileHdr.Length + strFileTlr.Length + info.Length
Dim io As System.IO.Stream
io = GetStream()
WriteString(io, strFields)
WriteString(io, strFileHdr)
Me.WriteFile(io, filename)
WriteString(io, strFileTlr)
GetResponse()
io.Close()
coRequest = Nothing
End Sub
Public Overridable Sub GetResponse()
If coFileStream Is Nothing Then
Dim stream As Stream
Dim response As WebResponse
Try
response = coRequest.GetResponse()
Catch web As WebException
response = web.Response
End Try
If response IsNot Nothing Then
stream = response.GetResponseStream()
Dim sr As StreamReader = New StreamReader(stream)
Dim str As String
ResponseText.Length = 0
For Each str In sr.ReadLine
ResponseText.Append(str)
Next
response.Close()
Else
Throw New Exception("MultipartForm: Error retrieving server response")
End If
End If
End Sub
you must write contentlength bytes to the request stream before calling begin getresponse
public void SendFile(string filename)
{
// The live of this object is only good during
// this function. Used mainly to avoid passing
// around parameters to other functions.
coRequest = (HttpWebRequest)WebRequest.Create(URL);
// Set use HTTP 1.0 or 1.1.
coRequest.ProtocolVersion = TransferHttpVersion;
coRequest.Method = "POST";
coRequest.ContentType = "multipart/form-data; boundary=" + BeginBoundary;
coRequest.Headers.Add("Cache-Control", "no-cache");
coRequest.KeepAlive = true;
string strFields = GetFormfields();
string strFileHdr = GetFileheader(filename);
string strFileTlr = GetFiletrailer();
FileInfo info = new FileInfo(filename);
coRequest.ContentLength = strFields.Length +
strFileHdr.Length +
strFileTlr.Length +
info.Length;
System.IO.Stream io;
io = GetStream();
WriteString(io, strFields);
WriteString(io, strFileHdr);
this.WriteFile(io, filename);
WriteString(io, strFileTlr);
GetResponse();
io.Close();
// End the life time of this request object.
coRequest = null;
}
public virtual void GetResponse()
{
if (null == coFileStream)
{
Stream stream;
WebResponse response;
try
{
response = coRequest.GetResponse();
}
catch (WebException web)
{
response = web.Response;
}
if (null != response)
{
stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string str;
ResponseText.Length = 0;
while ((str = sr.ReadLine()) != null)
ResponseText.Append(str);
response.Close();
}
else
throw new Exception("MultipartForm: Error retrieving server response");
}
}
And it works fine!Public Sub WriteString(ByVal stream As Stream, ByVal str As String)
Dim postData As Byte() = System.Text.Encoding.ASCII.GetBytes(str)
stream.Write(postData, 0, postData.Length)
End Sub
Public Sub WriteFile(ByVal stream As Stream, ByVal filename As String)
Using readIn As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
readIn.Seek(0, SeekOrigin.Begin)
Dim fileData As Byte() = New Byte(BufferSize - 1) {}
Dim bytes As Integer
Dim x = readIn.Read(fileData, 0, BufferSize)
bytes = x
'Do While (bytes = x) > 0
' stream.Write(fileData, 0, bytes)
' x = readIn.Read(fileData, 0, BufferSize)
'Loop
'While ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
' stream.Write(fileData, 0, bytes)
'End While
While (CSharpImpl.__Assign(bytes, readIn.Read(fileData, 0, BufferSize))) > 0
stream.Write(fileData, 0, bytes)
End While
End Using
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.Collections
Imports System.Net
Namespace DemoFileUpload
Public Class MultipartForm
Private coFormFields As Hashtable
Protected coRequest As HttpWebRequest
Private coFileStream As Stream
Private Shared CONTENT_DISP As String = "Content-Disposition: form-data; name="
Public Property TransferHttpVersion As Version
Public Property FileContentType As String
Public Sub New(ByVal url As String)
sURL = url
coFormFields = New Hashtable()
ResponseText = New StringBuilder()
BufferSize = 1024 * 10
BeginBoundary = "ou812--------------8c405ee4e38917c"
TransferHttpVersion = HttpVersion.Version11
FileContentType = "application/pdf"
End Sub
Private _BeginBoundary As String
Public Property BeginBoundary As String
Get
Return _BeginBoundary
End Get
Set(ByVal value As String)
_BeginBoundary = value
ContentBoundary = "--" & BeginBoundary
EndingBoundary = ContentBoundary & "--"
End Set
End Property
Protected Property ContentBoundary As String
Protected Property EndingBoundary As String
Public Property ResponseText As StringBuilder
Public Property sURL As String
Public Property BufferSize As Integer
Public Sub SetFilename(ByVal path As String)
coFileStream = New System.IO.FileStream(path, FileMode.Create, FileAccess.Write)
End Sub
Public Sub SetField(ByVal key As String, ByVal str As String)
coFormFields(key) = str
End Sub
Public Overridable Function GetStream() As Stream
Dim stream As Stream
If coFileStream Is Nothing Then
stream = coRequest.GetRequestStream()
Else
stream = coFileStream
End If
Return stream
End Function
Public Overridable Sub GetResponse()
If coFileStream Is Nothing Then
Dim stream As Stream
Dim response As WebResponse
Try
response = coRequest.GetResponse()
Catch web As WebException
response = web.Response
End Try
If response IsNot Nothing Then
stream = response.GetResponseStream()
Dim sr As StreamReader = New StreamReader(stream)
Dim str As String
ResponseText.Length = 0
For Each str In sr.ReadLine
ResponseText.Append(str)
Next
response.Close()
Else
Throw New Exception("MultipartForm: Error retrieving server response")
End If
End If
End Sub
Public Sub SendFile(ByVal filename As String)
coRequest = CType(WebRequest.Create(sURL), HttpWebRequest)
coRequest.ProtocolVersion = TransferHttpVersion
coRequest.Method = "POST"
coRequest.ContentType = "multipart/form-data; boundary=" & BeginBoundary
coRequest.Headers.Add("Cache-Control", "no-cache")
coRequest.KeepAlive = True
Dim strFields As String = GetFormfields()
Dim strFileHdr As String = GetFileheader(filename)
Dim strFileTlr As String = GetFiletrailer()
Dim info As FileInfo = New FileInfo(filename)
coRequest.ContentLength = strFields.Length + strFileHdr.Length + strFileTlr.Length + info.Length
Dim io As System.IO.Stream
io = GetStream()
WriteString(io, strFields)
WriteString(io, strFileHdr)
Me.WriteFile(io, filename)
WriteString(io, strFileTlr)
GetResponse()
io.Close()
coRequest = Nothing
End Sub
Public Sub WriteString(ByVal stream As Stream, ByVal str As String)
Dim postData As Byte() = System.Text.Encoding.ASCII.GetBytes(str)
stream.Write(postData, 0, postData.Length)
End Sub
Public Function GetFormfields() As String
Dim str As String = ""
Dim myEnumerator As IDictionaryEnumerator = coFormFields.GetEnumerator()
While myEnumerator.MoveNext()
str += ContentBoundary & vbCrLf & CONTENT_DISP & """" & myEnumerator.Key & """" & vbCrLf & vbCrLf & myEnumerator.Value & vbCrLf
End While
Return str
End Function
Public Function GetFileheader(ByVal filename As String) As String
Return ContentBoundary & vbCrLf & CONTENT_DISP & """file""; filename=""" & Path.GetFileName(filename) & """" & vbCrLf & "Content-type: " & FileContentType & vbCrLf & vbCrLf
End Function
Public Function GetFiletrailer() As String
Return vbCrLf & EndingBoundary
End Function
Public Sub WriteFile(ByVal stream As Stream, ByVal filename As String)
Using readIn As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
readIn.Seek(0, SeekOrigin.Begin)
Dim fileData As Byte() = New Byte(BufferSize - 1) {}
Dim bytes As Integer
Dim x = readIn.Read(fileData, 0, BufferSize)
bytes = x
'Do While (bytes = x) > 0
' stream.Write(fileData, 0, bytes)
' x = readIn.Read(fileData, 0, BufferSize)
'Loop
'While ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
' stream.Write(fileData, 0, bytes)
'End While
While (CSharpImpl.__Assign(bytes, readIn.Read(fileData, 0, BufferSize))) > 0
stream.Write(fileData, 0, bytes)
End While
End Using
End Sub
Private Class CSharpImpl
<Obsolete("Please refactor calling code to use normal Visual Basic assignment")>
Shared Function __Assign(Of T)(ByRef target As T, value As T) As T
target = value
Return value
End Function
End Class
End Class
End Namespace
If FileUpload1.UploadedFiles.Count > 0 Then
For Each f As UploadedFile In FileUpload1.UploadedFiles
Dim path As String = Server.MapPath("../storage/Files/Contracts/")
Dim fileName As String = path & f.GetName
f.SaveAs(path & f.GetName)
' FileUpload1.PostedFile.SaveAs(path & FileUpload1.FileName)
Dim form As MultipartForm = New MultipartForm("https://theurl")
form.SetField("access_token", "*****")
form.SetField("recipient_email", "n****r@gmail.com")
form.SetField("recipient_name", "Peter Nordberg")
form.SendFile(fileName)
Dim s As StringBuilder = form.ResponseText
If s.ToString().ToLower().Contains("success") Then
lblSuccess.Visible = True
Else
lblSuccess.Visible = True
lblSuccess.Text = "Error"
lblSuccess.ForeColor = Color.Red
End If
Next
End If
System.Net.ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse
using (dataStream = Webrequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
dataStream = Webrequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
Public Sub SendFile(ByVal filename As String)
coRequest = CType(WebRequest.Create(sURL), HttpWebRequest)
coRequest.ProtocolVersion = TransferHttpVersion
coRequest.Method = "POST"
coRequest.ContentType = "multipart/form-data; boundary=" & BeginBoundary
coRequest.Headers.Add("Cache-Control", "no-cache")
coRequest.KeepAlive = True
Dim strFields As String = GetFormfields()
Dim strFileHdr As String = GetFileheader(filename)
Dim strFileTlr As String = GetFiletrailer()
Dim info As FileInfo = New FileInfo(filename)
coRequest.ContentLength = strFields.Length + strFileHdr.Length + strFileTlr.Length + info.Length
Dim io As System.IO.Stream
io = GetStream()
WriteString(io, strFields)
WriteString(io, strFileHdr)
Me.WriteFile(io, filename)
WriteString(io, strFileTlr)
GetResponse()
io.Close()
coRequest = Nothing
End Sub
Public Sub WriteString(ByVal stream As Stream, ByVal str As String)
Dim postData As Byte() = System.Text.Encoding.ASCII.GetBytes(str)
stream.Write(postData, 0, postData.Length)
End Sub
 Public Sub WriteFile(ByVal stream As Stream, ByVal filename As String)
Using readIn As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
readIn.Seek(0, SeekOrigin.Begin)
Dim fileData As Byte() = New Byte(BufferSize - 1) {}
Dim bytes As Integer
Dim x = readIn.Read(fileData, 0, BufferSize)
bytes = x
'Do While (bytes = x) > 0
' stream.Write(fileData, 0, bytes)
' x = readIn.Read(fileData, 0, BufferSize)
'Loop
'While ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
' stream.Write(fileData, 0, bytes)
'End While
While (CSharpImpl.__Assign(bytes, readIn.Read(fileData, 0, BufferSize))) > 0
stream.Write(fileData, 0, bytes)
End While
End Using
End Sub
Const vbstream As String = "c:\temp\vbstream.bin"
Dim fs As New FileStream( vbstream, FileMode.OpenOrCreate, FileAccess.Write)
then repeat all write statements to the io stream by using 'fs' instead. string csstream = @"c:\temp\csstream.bin";
FileStream fs = new FileStream(csstream, FileMode.OpenOrCreate, FileAccess.Write);
WriteString(io, strFields)
WriteString(fs, "---01---")
WriteString(fs, strFields)
WriteString(fs, "---02---")
WriteString(fs, strFileHdr)
public void WriteFile(Stream stream, string filename)
{
using (FileStream readIn = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
byte[] fileData = new byte[BufferSize];
int bytes;
while ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
{
// read the file data and send a chunk at a time
stream.Write(fileData, 0, bytes);
}
}
}
Public Sub WriteFile(ByVal stream As Stream, ByVal filename As String)
Using readIn As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
readIn.Seek(0, SeekOrigin.Begin)
Dim fileData As Byte() = New Byte(BufferSize - 1) {}
Dim bytes As Integer
Dim x = readIn.Read(fileData, 0, BufferSize)
bytes = x
'Do While (bytes = x) > 0
' stream.Write(fileData, 0, bytes)
' x = readIn.Read(fileData, 0, BufferSize)
'Loop
While ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
stream.Write(fileData, 0, bytes)
End While
'While (CSharpImpl.__Assign(bytes, readIn.Read(fileData, 0, BufferSize))) > 0
' stream.Write(fileData, 0, bytes)
'End While
End Using
End Sub
Any idea how to do this in a right way in vb?fc path1 path2
While (CSharpImpl.__Assign(bytes, readIn.Read(fileData, 0, BufferSize))) >Â 0
public void WriteFile(Stream stream, string filename)
{
using (FileStream readIn = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
byte[] fileData = new byte[BufferSize];
int bytes;
while ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
{
// read the file data and send a chunk at a time
stream.Write(fileData, 0, bytes);
}
}
}
Using rdr As New BinaryReader(readIn)
'Read BufferSize bytes from the file
Dim bytes(BufferSize) As Byte
Dim bytesRead As Integer = rdr.Read(bytes, 0, BufferSize)
End Using
WriteString(io, strFileTlr)
Public Sub WriteFile(ByVal stream As Stream, ByVal filename As String)
Using readIn As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
readIn.Seek(0, SeekOrigin.Begin)
Dim fileData As Byte() = New Byte(BufferSize - 1) {}
'Dim bytes As Integer
' Dim x = readIn.Read(fileData, 0, BufferSize)
' bytes = x
Using rdr As New BinaryReader(readIn)
'Read BufferSize bytes from the file
Dim bytes(BufferSize) As Byte
Dim bytesRead As Integer = rdr.Read(bytes, 0, BufferSize)
End Using
'Do While (bytes = x) > 0
' stream.Write(fileData, 0, bytes)
' x = readIn.Read(fileData, 0, BufferSize)
'Loop
'While ((bytes = readIn.Read(fileData, 0, BufferSize)) > 0)
' stream.Write(fileData, 0, bytes)
'End While
'While (CSharpImpl.__Assign(bytes, readIn.Read(fileData, 0, BufferSize))) > 0
' stream.Write(fileData, 0, bytes)
'End While
End Using
End Sub
"System.Net.ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse" error when calling to the "BeginGetResponse" method of the web request.
Public Sub WriteFile(ByVal stream As Stream, ByVal filename As String)
Public Sub WriteFile(ByRef stream As Stream, ByVal filename As String)
Using rdr As New BinaryReader(readIn)
Dim bytes(BufferSize) As Byte
Dim bytesRead As Integer = 0
While ( (bytesRead = rdr.Read(bytes, 0, BufferSize) ) > 0)
stream.Write(bytes, 0, bytesRead)
End While
End Using
the WriteString and especially WriteFile in VB could have different defaults regarding line feeds, binary data, alignment or length attributes.
you may consider writing byte arrays with explicit length instead of strings or file contents.
Open in new window
Sara