Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A web based FTP client

0.00/5 (No votes)
21 Dec 2009 1  
A web application for accessing FTP.

Introduction

The Microsoft .NET framework provides a powerful library to access FTP sites and their content. In this article, we discuss how to access them from within web application and stream files from FTP and dump them wherever you want.

Using the code

The code has two parts:

  • FTP Helper - The project containing files for the FTP methods.
  • FTP Web - The web application for FTP.

The FTPConnection class must be serialized because I use it in the ViewState.

[Serializable]
public class FTPConnection

Here is the method used to connect to an FTP site:

public FtpWebRequest ConnectToFtp(string Method)
{
    FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(_url));
    ftpRequest.UseBinary = true;
    ftpRequest.Credentials = new NetworkCredential(_username, _password);
    ftpRequest.Method = Method;
    ftpRequest.Proxy = null;
    ftpRequest.KeepAlive = false;
    ftpRequest.UsePassive = false;
    return ftpRequest;
}

Now we can get the files list including the name and fully qualified paths from a specific URL:

/// <summary>
/// Get all files in ftp folder
/// </summary>
/// <param name="FolderUrl"></param>
/// <returns></returns>
public Dictionary<string, string> GetFileList(string FolderUrl)
{
    StringBuilder filesstring = new StringBuilder();
    WebResponse webResponse = null;
    StreamReader sreader = null;
     /// I use string type Dictionary to get both filename and filename with path
    Dictionary<string, string> Files = new Dictionary<string, string>();
    try
    {
        //you can change url to connect to ftp according to your need
        FtpWebRequest ftpRequest = ConnectToFtp(FolderUrl, 
                       WebRequestMethods.Ftp.ListDirectory);

        webResponse = ftpRequest.GetResponse();
        sreader = new StreamReader(webResponse.GetResponseStream());
        string strline = sreader.ReadLine();
        while (strline != null)
        {
            //Add filename and filename with path to dictionary
            Files.Add(strline, FolderUrl +"/"+ strline);                
        }         
       
        return Files;
    }
    catch (Exception ex)
    {
        //do any thing with exception
        return null;
    }
    finally
    {
        if (sreader != null)
        {
            sreader.Close();
        }
        if (webResponse != null)
        {
            webResponse.Close();
        }
    }
}

Here is how we get the downloadable file bytes:

public byte[] DownloadFileFromFtp(string fileUrl)
{
    StringBuilder filesstring = new StringBuilder();
    WebResponse webResponse = null;
    try
    {
        FtpWebRequest ftpRequest = ConnectToFtp(fileUrl, 
                                     WebRequestMethods.Ftp.DownloadFile);
        ftpRequest.UseBinary = true;
        webResponse = ftpRequest.GetResponse();

        FtpWebResponse response = (FtpWebResponse)webResponse;
        
        Stream dfileResponseStream = response.GetResponseStream();
        
        
        int Length = 1024;
        
        Byte[] buffer = new Byte[Length];
        // collect all bytes of file
        List<byte> filebytes = new List<byte>();
        int bytesRead = dfileResponseStream.Read(buffer, 0, Length);
        while (bytesRead > 0)
        {
            for(int i= 0;i<bytesRead;i++)
            // read file byte in buffer and add it to list
                filebytes.Add(buffer[i]);
            
            bytesRead = dfileResponseStream.Read(buffer, 0, Length);
        }
        response.Close();
        return filebytes.ToArray(); // return complete byte array
    }
    catch (Exception ex)
    {
        //do any thing with exception
        return null;
    }
    finally
    {
        if (webResponse != null)
        {
            webResponse.Close();
        }
    }
}

We are done with the basic FTP methods. We will now look at the web application part.

I store the FTPHelper.FTPConnection object in the ViewState, because I want to use the same instance multiple times on a page.

public FTPHelper.FTPConnection FTP
{
    set
    {
        ViewState["FTP"] = value;
    }
    get
    {
        return ViewState["FTP"] == null ? null : 
          (FTPHelper.FTPConnection)ViewState["FTP"];
    }
}

Set the FTP URL, username, and password for the FTP site using the interface below:

login.png

Now connect to the FTP site and retrieve the root directories and files:

public void ConnectToFtp()
{
    try
    {
       FTP = new FTPHelper.FTPConnection(txtFTPUrl.Text.ToLower().Replace(
                  "ftp://",""), txtUser.Text, txtPassword.Text);
        Dictionary<string, string> Files = FTP.GetFileList(FTP._url);
       
        lblWelcome.Text = "<strong> Welcome </strong> " + txtUser.Text;
        tbLogin.Visible = false;
        foreach (string ky in Files.Keys)
        {
            TreeNode trParent = new TreeNode();
            trParent.Text = (string)ky; // file name
            trParent.Value = Files[ky]; // fully qualified name

            trVFiles.Nodes.Add(trParent);
        }
    }
    catch(Exception ex)
    {
        tbLogin.Visible = false;
        lblWelcome.Text = ex.Message;
        lblWelcome.ForeColor = System.Drawing.Color.Red;
    }
}

Capture the SelectedNodeChanged event of the TreeView control to get the directory and files in the selected directory node:

protected void trVFiles_SelectedNodeChanged(object sender, EventArgs e)
{
     Dictionary<string,string> _filesInFolder = FTP.GetFileList(trVFiles.SelectedValue);
     Dictionary<string, string> _onlyfiles = new Dictionary<string, string>();

     foreach (string key in _filesInFolder.Keys)
     {
         // checking if file is directory 
         if (key.IndexOf('.') == -1)
         {
             TreeNode trParent = new TreeNode();
             trParent.Text = (string)key;
             trParent.Value = _filesInFolder[key];

           // appending directory to selected parent directory
             trVFiles.SelectedNode.ChildNodes.Add(trParent); 
         }
         else
         {
             _onlyfiles.Add(key, _filesInFolder[key]); // seperate the files 
         }
     }
     trVFiles.SelectedNode.Expand(); //expand the selected node
     BindGrid(_onlyfiles); // bind the grid with files separated
}

Finally, get the RowCommand event to download the desired file:

protected void grdDetailView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    //CommandArgument contain the fully qualified name of the file
    byte[] _downFile = FTP.DownloadFileFromFtp(e.CommandArgument.ToString());
    string _fname =e.CommandArgument.ToString();
    Response.ContentType = "application/"+_fname.Split('.')[1];
    Response.AddHeader("Content-disposition", 
                       "attachment; filename=" + _fname);
    // stream the file byte on ftp
    Response.OutputStream.Write(_downFile, 0, _downFile.Length);
    Response.End();
}

That's all.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here