WebRequest and WebResponse


Instead of using the WebClient class, you can use the WebRequest class to communicate with a Web or a FTP server, and it is also possible to read files. Behind the scenes, the WebClient class itself makes use of WebRequest.

The WebRequest class is always used in combination with the WebResponse class. First, you have to define the request that will be sent to the server by configuring a WebRequest object. Next, you can invoke the method GetResponse, which sends the request to the server and returns the response from the server in the WebResponse class.

The WebRequest and WebResponse classes are abstract classes, and thus not directly used. These classes are base classes as shown in Figure 29-8, and .NET 2.0 offers concrete implementations for the HTTP, FTP, and file protocols. Concrete implementations of these base classes are HttpWebRequest, FtpWebRequest, FileWebRequest, HttpWebResponse, FtpWebResponse, and FileWebResponse. The HTTP protocol is used by the HttpWebXXX classes, the FtpWebXXX classes make use of the FTP protocol, and the FileWebXXX classes allow you to access the file system.

image from book
Figure 29-8

Writing an FTP client is a simple task with help of the FtpWebRequest class. In the next Try It Out, you create a Windows application that downloads files from an FTP server.

Try It Out – Get a File from an FTP server

image from book
  1. Create a new Windows application named FtpClient in the directory C:\BegVCSharp\ Chapter29.

  2. Rename the file Form1.cs to FtpClientForm.cs. This also renames the class Form1 to FtpClientForm.

  3. Add controls to the main dialog, as shown in Figure 29-9.

    image from book
    Figure 29-9

    The controls from this form and their property settings are shown in the following table.

    Control Type

    Name

    Text Property

    FtpClientForm

    FtpClientForm

    FTP Client

    ListBox

    listFiles

    Label

    labelServer

    Server:

    Label

    labelUsername

    Username:

    Label

    labelPassword

    Password:

    TextBox

    textServer

    ftp://

    TextBox

    textUsername

    Anonymous

    TextBox

    textPassword

    Button

    buttonOpen

    Open

    Button

    buttonOpenDirectory

    Open Directory

    Button

    buttonGetFile

    Get File

    CheckBox

    checkBoxBinary

    Binary Mode

  4. Using the Property Editor set the Enabled property of the buttons buttonGetFile and buttonOpenDirectory to false. These buttons will only be active when a file is selected.

  5. Add a SaveFileDialog control to the form. This dialog will be used to ask the user where to store the file that is downloaded from the server.

  6. Import the System.Net and System.IO namespaces.

  7. Add the variable serverDirectory as a private member to the class FtpClientForm:

    public partial class FtpClientForm : Form { private string serverDirectory; 
  8. Add the helper method FillDirectoryList to the class FtpClientForm. This method fills the listbox with all the data that is inside the stream argument.

     private void FillDirectoryList(Stream stream) {    StreamReader reader = new StreamReader(stream);    string content = reader.ReadToEnd();    string[] files = content.Split('\n');    listFiles.DataSource = files;    reader.Close(); } 
  9. To make an initial connection to the server, using the Properties dialog, add a Click event handler to the button buttonOpen with the name OnOpen. Add the implementation to this handler as shown here:

    private void OnOpen(object sender, EventArgs e) { Cursor currentCursor = this.Cursor; FtpWebResponse response = null; Stream stream = null; try { this.Cursor = Cursors.WaitCursor; // Create the FtpWebRequest object. FtpWebRequest request =  (FtpWebRequest)WebRequest.Create(textServer.Text); request.Credentials = new NetworkCredential(textUsername.Text, textPassword.Text); request.Method = WebRequestMethods.Ftp.ListDirectory; // Send the request to the server. response = (FtpWebResponse)request.GetResponse(); // Read the response and fill the list box. stream = response.GetResponseStream(); FillDirectoryList(stream); serverDirectory = null; buttonOpenDirectory.Enabled = false; buttonGetFile.Enabled = false; } catch (Exception ex) { MessageBox.Show(ex.Message, "Error FTP Client",  MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (response != null) response.Close(); if (stream != null) stream.Close(); this.Cursor = currentCursor; } }

  10. To open specific directory on the server add a Click event handler to the button buttonOpenDirectory with the name OnOpenDirectory. Add the code to this handler as shown here:

    private void OnOpenDirectory(object sender, EventArgs e) { FtpWebResponse response = null; Stream stream = null; try { string subDirectory = listFiles.SelectedValue.ToString().Trim(); serverDirectory += "/" + subDirectory; Uri baseUri = new Uri(textServer.Text); Uri uri = new Uri(baseUri, serverDirectory); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri); request.Credentials = new NetworkCredential(textUsername.Text, textPassword.Text); request.Method = WebRequestMethods.Ftp.ListDirectory; response = (FtpWebResponse)request.GetResponse(); stream = response.GetResponseStream(); FillDirectoryList(stream); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error FTP Client",  MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (response != null) response.Close(); if (stream != null) stream.Close(); } }

  11. For downloading a file from the server, add a Click event handler named OnDownloadFile to the buttonGetFile button. Add the following code to this event handler method:

    private void OnDownloadFile(object sender, EventArgs e) { FtpWebResponse response = null; Stream inStream = null; Stream outStream = null; try { Uri baseUri = new Uri(textServer.Text); string filename = listFiles.SelectedValue.ToString().Trim(); string fullFilename = serverDirectory + @"/" + filename; Uri uri = new Uri(baseUri, fullFilename); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri); request.Credentials = new NetworkCredential(textUsername.Text, textPassword.Text); request.Method = WebRequestMethods.Ftp.DownloadFile; request.UseBinary = checkBoxBinary.Checked; response = (FtpWebResponse)request.GetResponse(); inStream = response.GetResponseStream(); saveFileDialog1.FileName = filename; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { outStream = File.OpenWrite(saveFileDialog1.FileName); byte[] buffer = new byte[4096]; int size = 0; while ((size = inStream.Read(buffer, 0, 4096)) > 0) { outStream.Write(buffer, 0, size); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error FTP Client",  MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (inStream != null) inStream.Close(); if (outStream != null) outStream.Close(); if (response != null) response.Close(); } } 

  12. To enable the Open Directory and Get File buttons, you must add an event handler for the SelectedIndexChanged event of the listFiles list box. Name the event handler OnFileSelection.

    private void OnFileSelection(object sender, EventArgs e) { buttonGetFile.Enabled = true; buttonOpenDirectory.Enabled = true; }
  13. After compiling the application, you can try it out. Start the application, which presents a screen like that shown in Figure 29-10. Enter an FTP server to connect to (for example, ftp://ftp.microsoft.com), and click the Open button. FTP servers that support anonymous users accept the username Anonymous. Some FTP servers that allow anonymous users check for a password that is in valid e-mail address format. This behavior is not used for security reasons but to write the file requests to a log file.

    image from book
    Figure 29-10

    After a successful connection, the server's files and directories appear in the list box, as shown in Figure 29-11. Now, you can open other directories by clicking the Open Directory button, or download files by clicking the Get File button.

    image from book
    Figure 29-11

How It Works

When you send a request to an FTP server, an FtpWebRequest object must be created. the FtpWebRequest object is created by the factory method WebRequest.Create(). This method creates either an FtpWebRequest, an HttpWebRequest, or a FileWebRequest object, depending on the URL string that is passed to the method.

FtpWebRequest request =       (FtpWebRequest)WebRequest.Create(textServer.Text); 

After the FtpWebRequest object is created, it must be configured by setting its properties. The property Credentials allows setting the username and password used to access the server. the Method property defines the FTP request that should be sent to the server.

The FTP protocol allows commands that are very similar to the HTTP protocol's commands. The HTTP protocol uses commands like GET, HEAD and POST. The FTP protocol's commands are defined in RFC 959 (www.ietf.org/rfc/rfc0959.txt): RETR to download files, STOR to upload files, MKD to create a directory, and LIST to get the files from a directory. With .NET there's no need to know all these FTP commands, because the WebRequestMethods class has these commands defined. WebRequestMethods.Ftp.ListDirectory creates a LIST request to be sent to the server, WebRequestMethods.Ftp.DownloadFiles is used to download a file from the server.

request.Credentials = new NetworkCredential(textUsername.Text,       textPassword.Text); request.Method = WebRequestMethods.Ftp.ListDirectory;

When the request is defined, it can be sent to the server. the GetResponse() method sends the request to the server and waits until a response is received.

response = (FtpWebResponse)request.GetResponse();

To access the data from the response, the GetResponseStream() method returns a stream. In response to the WebRequestMethods.Ftp.ListDirectory request, the response stream contains all the filenames from the requested server directory. After an WebRequestMethods.Ftp.DownladFile request, the response stream contains the content of the requested file.

stream = response.GetResponseStream();

The returned stream containing the server directory's file listing is dealt with in the FillDirectoryList() method. The stream is read by using a StreamReader. The method ReadToEnd() returns a string of all the filenames that have been returned by the server. The filenames are separated by the newline character that is used to create a string array containing all filenames. This string array is set as the data source of the ListBox to display it in the form as follows:

private void FillDirectoryList(Stream stream) {    StreamReader reader = new StreamReader(stream);    string content = reader.ReadToEnd();    string[] files = content.Split('\n');    listFiles.DataSource = files;    reader.Close(); }

The stream that is received from the download file request is dealt with in the OnDownloadFile() method. A SaveFileDialog is opened so that the user can specify in which directory to store the file. the saveFileDialog1 FileName property returns the directory and filename selected by the user. the File class OpenWrite() method returns the stream indicating where the file from the server can be stored. The stream returned from the FTP server is read in a while loop and written into the stream of the local file.

Note

You can read more about dialogs in Chapter 16.

inStream = response.GetResponseStream();     saveFileDialog1.FileName = filename;     if (saveFileDialog1.ShowDialog() == DialogResult.OK) {    outStream = File.OpenWrite(saveFileDialog1.FileName);    byte[] buffer = new byte[4096];    int size = 0;    while ((size = inStream.Read(buffer, 0, 4096)) > 0)    {       outStream.Write(buffer, 0, size);    } }

Now you have seen how .NET classes can be used with well-known application protocols. If you want to create your own application protocol that is based on TCP, you can use the TcpListener and TcpClient classes, which are covered in the next section.

image from book




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net