Click here to Skip to main content
Click here to Skip to main content

A web based FTP client

, 21 Dec 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Syed Danish Aftab
Software Developer (Senior) Sidat Hyder Morshed Associates Pvt Ltd
Pakistan Pakistan
MCP,MCTS

Comments and Discussions

 
QuestionThis should get it running Pinmemberduckkiller5317-Jul-13 9:07 
QuestionObject reference not set to an instance of an object ERROR PinmemberMember 998960123-Apr-13 23:01 
QuestionError Pinmembernater30328-Oct-12 12:50 
GeneralMy vote of 1 PinmvpDave Kreskowiak21-Dec-09 8:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.141022.2 | Last Updated 21 Dec 2009
Article Copyright 2009 by Syed Danish Aftab
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid