Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Build a Photo Viewer Using the New FTP Classes in .NET 2.0

Yet another highly useful but underappreciated feature of .NET 2.0? How about the FTPWebRequest and FtpWebResponse classes? These nifty classes let you built FTP file access right into your applications. See how it's done with this handy photo viewer example.


advertisement
ne of the features released with the 2.0 version of .NET was support for FTP. In .NET 2.0, you can now programmatically access FTP servers using the FtpWebRequest and FtpWebResponse managed classes (both derived from the WebRequest and WebResponse classes).

To illustrate the usefulness of using FTP in your .NET applications, I will build a Photo Viewer Windows application that accesses an FTP server. Using this application, users can upload photos to an FTP server and at the same time view images stored on the FTP server. This application is useful to companies who may need to access images uploaded by its partners. A good example is insurance companies, who may need to view photographs of car damages taken by workshop mechanics in order to estimate the cost of repair. Rather than build a complex Web application, the workshop and insurance companies can simply use this application to quickly upload and view photos.

Figure 1 shows what the application will look like when completed.



Creating the Application
Using Visual Studio 2005, create a new Windows application and name it PhotoViewer. Populate the default Form1 with the controls shown in Figure 2. The controls are:

  • Button
  • GroupBox
  • Label
  • PictureBox
  • TextBox
  • ToolStripStatusLabel
  • TreeView
The TreeView control is used to display the directory structure of the FTP server.


Figure 1. The completed Photo Viewer application.
 
Figure 2. Populate Form1 with the various controls shown.

Besides those listed above, you'll also need to add an ImageList control to Form1 to contain three images representing an opened folder, a closed folder, and an image file. You can specify these images by specifying them in the control's Image property (see Figure 3).

You also need to associate the ImageList control with the TreeView control by specifying ImageList1 in the ImageList property of the TreeView control (TreeView1).

Building the Directory Tree and Displaying Images
Switching to the code-behind of Form1, import the following namespaces:

Imports System.Net Imports System.IO

Declare the following constants and member variables:

Public Class Form1 '---FTP server--- Const ftpServer As String = "ftp://127.0.0.1" '---constants for the icon images--- Const icoOpen = 0 Const icoClose = 1 Const icoPhoto = 2 '---login credentials for the FTP server--- Private Username As String = "anonymous" Private Password As String = "password"

When the form is loaded, display a node representing the root directory:

Private Sub Form1_Load( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load Try '—-create the root node for the TreeView—- Dim node As New TreeNode node.ImageIndex = icoClose node.SelectedImageIndex = icoOpen node.Text = "/" '---add the root node to the control--- TreeView1.Nodes.Add(node) '—-add the dummy child node to the root node—- node.Nodes.Add("") '---select the root node--- TreeView1.SelectedNode = node Catch err As Exception MsgBox(err.ToString) End Try End Sub

Note that I add a dummy node after each node is created. This is to ensure that the current node can be expanded to reveal subdirectories (even if there are none). This is shown in Figure 4.

Figure 3. Add three images to the ImageList control.
When a node is expanded (by clicking on the "+" symbol), the TreeView1_BeforeExpand event is called. You have to write code that checks to see if the current node is a leaf node (meaning it is not a directory, but a file). If it is a leaf node, exit the method. Otherwise you need to display its sub-directories (if any).

You should also change the current node icon to "open" if the node is selected and "closed" if the node is not selected. Below is the code for expanding folders and displaying the proper icon at each node:

Private Sub TreeView1_BeforeExpand( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) _ Handles TreeView1.BeforeExpand '---if leaf node (photo) then exit--- If e.Node.ImageIndex = icoPhoto Then Return '---remove the dummy node and display ' the subdirectories and files--- Try '---clears all the nodes and...--- e.Node.Nodes.Clear() '---create the nodes again--- BuildDirectory(e.Node) Catch err As Exception ToolStripStatusLabel1.Text = err.ToString End Try '---change the icon for this node to open--- If e.Node.GetNodeCount(False) > 0 Then e.Node.ImageIndex = icoClose e.Node.SelectedImageIndex = icoOpen End If End Sub

The BuildDirectory() subroutine displays all the files and subdirectories within the current directory in the TreeView control. Before I look at the definition of the BuildDirectory() subroutine, I'll define the GetDirectoryListing() function, whose main job it is to request from the FTP server the directory listing of a particular path:

'---Get the file/dir listings and return them as a string array--- Private Function GetDirectoryListing(ByVal path As String) _ As String() Try Dim ftpReq As FtpWebRequest = WebRequest.Create(path) ftpReq.Method = WebRequestMethods.Ftp.ListDirectoryDetails ftpReq.Credentials = New NetworkCredential( _ Username, Password) Dim FTPResp As FtpWebResponse = ftpReq.GetResponse Dim ftpRespStream As Stream = FTPResp.GetResponseStream Dim reader As StreamReader reader = New StreamReader( _ ftpRespStream, System.Text.Encoding.UTF8) '---obtain the result as a string array--- Dim result() As String = reader.ReadToEnd.Split(vbLf) FTPResp.Close() Return result Catch ex As Exception MsgBox(ex.ToString) Return Nothing End Try End Function

Figure 4. Add a dummy node to a node so that it can be expanded.
To view the directory listing of an FTP server:
  • Create an instance of the FtpWebRequest class using the Create() method of the WebRequest class. The Create() method takes in a URI parameter (containing the full FTP path).
  • Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case the command is ListDirectoryDetails.
  • Specify the login credential to the FTP server.
  • Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
  • Retrieve the stream that contains response data sent from an FTP server using the GetResponseStream() method from the FtpWebResponse class.
  • You can use a StreamReader object to read the directory listing.
The directory listings are each separated by a LineFeed (vbLf) character. If your FTP server is configured with MS-DOS directory listing style (see Figure 5), the directory listing looks something like this:

12-11-06 10:54PM 2074750 DSC00098.JPG 12-11-06 10:54PM 2109227 DSC00099.JPG 12-11-06 10:49PM <DIR> George 12-11-06 10:49PM <DIR> James 12-11-06 10:58PM <DIR> Wei-Meng Lee

Author's Note: For this article, I am using the FTP service available in Windows XP. Also note that you need to give write permission to users so that they can create new directories and upload files to the FTP server.

As all subdirectories have the <DIR> field, you can simply differentiate subdirectories from files in the BuildDirectory() subroutine by looking for the "<DIR>" words:

'---Build the directory in the TreeView control--- Private Sub BuildDirectory(ByVal ParentNode As TreeNode) Dim listing() As String = _ GetDirectoryListing(ftpServer & ParentNode.FullPath) For Each line As String In listing If line = String.Empty Then Exit For Dim node As New TreeNode If line.Substring(24, 5) = "

" Then '---this is a directory--- '---create a new node to be added--- With node .Text = line.Substring(39) .ImageIndex = icoClose .SelectedImageIndex = icoOpen '---add the dummy child node--- .Nodes.Add("") End With ParentNode.Nodes.Add(node) Else '---this is a normal file--- '---create a new node to be added--- With node .Text = line.Substring(39) .ImageIndex = icoPhoto .SelectedImageIndex = icoPhoto End With ParentNode.Nodes.Add(node) End If Next End Sub
When a node is selected, you first obtain the current path of the node and then display its path in the status bar if it is a folder. If it is an image node, download and display the photo using the DownloadImage() subroutine:

Private Sub TreeView1_AfterSelect( _ ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.TreeViewEventArgs) _ Handles TreeView1.AfterSelect '---always ignore the first "/" char--- Dim FullPath As String = _ ftpServer & e.Node.FullPath.Substring(1).Replace(vbCr, "") '---display the current folder selected--- If e.Node.ImageIndex <> icoPhoto Then ToolStripStatusLabel1.Text = FullPath Return End If '---download image--- DownloadImage(FullPath) End Sub

Figure 5. Choose the directory listing style of the FTP server, in this case MS-DOS.
The DownloadImage() subroutine downloads an image from the FTP server and displays the image in a PictureBox control:

'---Download the image from the FTP server--- Private Sub DownloadImage(ByVal path As String) Try Dim filename As String = path Dim ftpReq As FtpWebRequest = WebRequest.Create(filename) ftpReq.Method = WebRequestMethods.Ftp.DownloadFile ftpReq.Credentials = New NetworkCredential( _ Username, Password) ToolStripStatusLabel1.Text = "Downloading image..." & path Application.DoEvents() Dim FTPResp As FtpWebResponse = ftpReq.GetResponse Dim ftpRespStream As Stream = FTPResp.GetResponseStream PictureBox1.Image = Image.FromStream(ftpRespStream) FTPResp.Close() ToolStripStatusLabel1.Text = _ "Downloading image...complete (" & path & ")" Catch ex As Exception MsgBox(ex.Message) End Try End Sub

To download an image file using FTP and then bind it to a PictureBox control:
  • Create an instance of the FtpWebRequest class using the Create() method of the WebRequest class. The Create() method takes in a URI parameter (containing the path for the text file to be downloaded).
  • Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case the command is DownloadFile.
  • Specify the login credential to the FTP server.
  • Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
  • Retrieve the stream that contains response data sent from an FTP server using the GetResponseStream() method from the FtpWebResponse class.
  • Use the FromStream() method from the Image class to convert the response from the FTP server (containing the image) into an image.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap