• 0

[VB .NET]


Question

EDIT: I'm sorry, I was so caught up in reading the code that I forgot to add a title to my post...

Hi Neowin! I have a dilemma on my hands... I am trying to create a simple program to upload a file to our FTP server but I am having some issues. I found this piece of code on the web which should work but I keep receiving a: "The requested URI is invalid for this FTP command." error when the code reaches the upload section:

Dim clsStream As System.IO.Stream = _

clsRequest.GetRequestStream()

Also, the debugger shows multiple instances of this exception: "A first chance exception of type 'System.Net.WebException' occurred in System.dll"

Has anyone have any idea of what this means? I tried to Google it but I couldn't find a straight answer to the subject.

    Private Sub cmdUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdUpload.Click
        Log("Acquiring information")

        ' These should come from an XML file
        ftpserver = "ftp://**********"
        ftpusername = "*********"
        ftppassword = "*********"

        Log("Connecting to: " & ftpserver)
        Dim clsRequest As System.Net.FtpWebRequest = _
    DirectCast(System.Net.WebRequest.Create(ftpserver), System.Net.FtpWebRequest)
        clsRequest.Credentials = New System.Net.NetworkCredential(ftpusername, ftppassword)
        clsRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile

        ' read in file
        Log("Reading file")
        Dim bFile() As Byte = System.IO.File.ReadAllBytes(strFilePath)

        ' upload file
        Log("Uploading file")
        clsRequest.UsePassive = False
        clsRequest.Proxy = Nothing
        Dim clsStream As System.IO.Stream = _
            clsRequest.GetRequestStream()
        clsStream.Write(bFile, 0, bFile.Length)

        ' close stream
        Log("Closing connection")
        clsStream.Close()
        clsStream.Dispose()

        ' complete
        Log("Complete")
        MsgBox("Upload complete")
    End Sub

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

  • 0

I figured I'd also include the full exception report. Also, the FTP server is IIS based. I've been trying all day and cannot come to a sensible conclusion on this issue...

System.Net.WebException was unhandled
  Message="The requested URI is invalid for this FTP command."
  Source="System"
  StackTrace:
       at System.Net.FtpWebRequest.GetRequestStream()
       at MASCO_Upload_Tool.frmMain.cmdUpload_Click(Object sender, EventArgs e) in C:\Upload Tool\frmMain.vb:line 59
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at MASCO_Upload_Tool.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Link to comment
Share on other sites

  • 0

What Uri are you actually using, typically, you would use the full Uri to the file, e.g. ftp://mydomain.com/test.txt:

Import System
Import System.IO
Import System.Net

...

Public Sub UploadFile(filePath As String, fileUri As String)
  Dim request As FtpWebRequest = DirectCast(WebRequest.Create(fileUri), FtpWebRequest)
  request.Credentials = New NetworkCredentials("username", "password")
  request.Method = WebRequestMethods.Ftp.UploadFile

  Dim file() As Byte = File.ReadAllBytes(filePath)

  Dim stream As Stream = request.GetRequestStream()
  stream.Write(file, 0, file.Length)
  stream.Close()
  stream.Dispose()
End Sub

Link to comment
Share on other sites

  • 0

You are right =)

I found this nifty piece of code that actually works, only issue is that the progressbar function does not work correctly... And the issue was the full path of the URI was not defined.

    Private Sub cmdUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdUpload.Click

        Dim client As New System.Net.WebClient()
        AddHandler client.UploadProgressChanged, AddressOf UpdateProgressBar
        With client
            .Credentials = New NetworkCredential( _
            "************", "************")
            .UploadFile("ftp://cchelpdesk/test.zip", _
            "C:\test.zip")
        End With
    End Sub

    Sub UpdateProgressBar(ByVal sender As Object, ByVal e As UploadProgressChangedEventArgs)
        If prgProgress.InvokeRequired Then
            prgProgress.Invoke( _
            New UploadProgressChangedEventHandler(AddressOf UpdateProgressBar), _
            sender, e)
            Exit Sub
        End If
        prgProgress.Value = CInt(prgProgress.Minimum + _
        ((prgProgress.Maximum - prgProgress.Minimum) * _
          e.ProgressPercentage) / 100)
    End Sub

Link to comment
Share on other sites

  • 0

Try this code (its untested and there is no exception handling). It provides an event (ProgressChanged) which you can subscribe to receive upload progress information.

Imports System
Imports System.IO
Imports System.Net
Imports System.Threading

Namespace FTPDemo
    ''' <summary>
    ''' Uploads a file to an FTP server. 
    ''' </summary>
    Public Class FileUploader
        Private thread As Thread
        Private _fileName As String
        Private _ftpUrl As Uri
        Private _credentials As NetworkCredential

        ''' <summary>
        ''' Event used to report progress changes.
        ''' </summary>
        Public OnProgressChanged As EventHandler(Of UploadEventArgs)

        ''' <summary>
        ''' Gets the file to be uploaded.
        ''' </summary>
        Public Property FileName As String
            Get
                Return _fileName
            End Get
            Private Set(ByVal value As String)
                _fileName = value
            End Set
        End Property

        ''' <summary>
        ''' Gets the remote FTP server url.
        ''' </summary>
        Public Property FtpUrl As Uri
            Get
                Return _ftpUrl
            End Get
            Private Set(ByVal value As Uri)
                _ftpUrl = value
            End Set
        End Property

        ''' <summary>
        ''' Gets the credentials used to log into the remote server.
        ''' </summary>
        Public Property Credentials As NetworkCredential
            Get
                Return _credentials
            End Get
            Private Set(ByVal value As NetworkCredential)
                _credentials = value
            End Set
        End Property

        ''' <summary>
        ''' Initialises a new instance of <see cref="FileUploader" />.
        ''' </summary>
        ''' <param name="fileName">The file to be uploaded.</param>
        ''' <param name="ftpUrl">The remote FTP server url.</param>
        ''' <param name="credentials">The credentials used to log into the remote server.</param>
        Public Sub New(ByVal fileName As String, ByVal ftpUrl As Uri, ByVal credentials As NetworkCredential)
            Me.FileName = fileName
            Me.FtpUrl = ftpUrl
            Me.Credentials = credentials

            thread = New Thread(AddressOf DoWork)
        End Sub

        ''' <summary>
        ''' Uploads the specified file.
        ''' </summary>
        Public Sub Upload()
            thread.Start()
        End Sub

        ''' <summary>
        ''' Pauses the upload.
        ''' </summary>
        Public Sub Pause()
            thread.Suspend()
        End Sub

        ''' <summary>
        ''' Resumes the upload.
        ''' </summary>
        Public Sub [Resume]()
            thread.[Resume]()
        End Sub

        ''' <summary>
        ''' Cancels the upload.
        ''' </summary>
        Public Sub Cancel()
            thread.Abort()
        End Sub

        ''' <summary>
        ''' The threaded method used to perform the upload.
        ''' </summary>
        Private Sub DoWork()
            Dim request As FtpWebRequest = DirectCast(WebRequest.Create(FtpUrl), FtpWebRequest)
            Dim chunk As Integer = 4096

            Dim fileInfo As FileInfo = New FileInfo(FileName)
            Dim length As Long = fileInfo.Length

            Dim buffer(chunk) As Byte
            Dim sent As Long = 0

            Dim requestStream As Stream = request.GetRequestStream()
            Dim fileStream As FileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)

            Dim read As Long = fileStream.Read(buffer, 0, chunk)
            While (read > 0)
                requestStream.Write(buffer, 0, read)
                sent += read

                Dim progress As Integer = CType((CType(sent, Decimal)) / (CType(length, Decimal)) * 100, Integer)
                ProgressChanged(New UploadEventArgs(FileName, FtpUrl, sent, length, progress))

                read = fileStream.Read(buffer, 0, chunk)
            End While

        End Sub

        ''' <summary>
        ''' Fires the progress changed event for any subscribers.
        ''' </summary>
        ''' <param name="e">The event arguments passed to any subscribers.</param>
        Private Sub ProgressChanged(e As UploadEventArgs)
            If (OnProgressChanged <> Nothing) Then
                OnProgressChanged(Me, e)
            End If
        End Sub
    End Class

    ''' <summary>
    ''' Represents event arguments passed to subscribers.
    ''' </summary>
    Public Class UploadEventArgs
        Inherits EventArgs

        Private _fileName As String
        Private _ftpUrl As Uri
        Private _sent As Long
        Private _totalSize As Long
        Private _percentageComplete As Integer

        ''' <summary>
        ''' Gets the file that is being uploaded.
        ''' </summary>
        Public Property FileName As String
            Get
                Return _fileName
            End Get
            Private Set(ByVal value As String)
                _fileName = value
            End Set
        End Property

        ''' <summary>
        ''' The remote server url.
        ''' </summary>
        Public Property FtpUrl As Uri
            Get
                Return _ftpUrl
            End Get
            Private Set(ByVal value As Uri)
                _ftpUrl = value
            End Set
        End Property

        ''' <summary>
        ''' The bytes sent to the server.
        ''' </summary>
        Public Property Sent As Long
            Get
                Return _sent
            End Get
            Private Set(ByVal value As Long)
                _sent = value
            End Set
        End Property

        ''' <summary>
        ''' The total size of the file, in bytes.
        ''' </summary>
        Public Property TotalSize As Long
            Get
                Return _totalSize
            End Get
            Private Set(ByVal value As Long)
                _totalSize = value
            End Set
        End Property

        ''' <summary>
        ''' The percentage complete of the upload.
        ''' </summary>
        Public Property PercentageComplete As Integer
            Get
                Return _percentageComplete
            End Get
            Private Set(ByVal value As Integer)
                _percentageComplete = value
            End Set
        End Property

        ''' <summary>
        ''' Initialises a new instance of <see cref="UploadEventArgs" />.
        ''' </summary>
        ''' <param name="fileName">The file that is being uploaded.</param>
        ''' <param name="ftpUrl">The remote server url.</param>
        ''' <param name="sent">The bytes sent to the server.</param>
        ''' <param name="totalSize">The total size of the file, in bytes.</param>
        ''' <param name="percentageComplete">The percentage complete of the upload.</param>
        Public Sub New(ByVal fileName As String, ByVal ftpUrl As Uri, ByVal sent As Long, ByVal totalSize As Long, ByVal percentageComplete As Integer)
            Me.FileName = fileName
            Me.FtpUrl = ftpUrl

            Me.Sent = sent
            Me.TotalSize = totalSize
            Me.PercentageComplete = PercentageComplete
        End Sub
    End Class
End Namespace

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.