tags:

views:

1972

answers:

3
A: 

I think we had a similar issue a while back, I don't remember the exact details though.

To prevent .net from issuing the cd command, see if setting the default directory for the user you're login in as is set to the directory you want to work in. You can just use a command line ftp client to check this out.

Sijin
+9  A: 

I just tested this on one of our dev servers and indeed there is a CWD issued by the .NET FtpWebRequest:

new connection from 172.16.3.210 on 172.16.3.210:21 (Explicit SSL)
hostname resolved : devpc
sending welcome message.
220 Gene6 FTP Server v3.10.0 (Build 2) ready...
USER testuser
testuser, 331 Password required for testuser.
testuser, PASS ****
testuser, logged in as "testuser".
testuser, 230 User testuser logged in.
testuser, OPTS utf8 on
testuser, 501 Please CLNT first.
testuser, PWD
testuser, 257 "/" is current directory.
testuser, CWD /
testuser, change directory '/' -> 'D:\testfolder' --> Access allowed.
testuser, 250 CWD command successful. "/" is current directory.
testuser, TYPE I
testuser, 200 Type set to I.
testuser, PORT 172,16,3,210,4,127
testuser, 200 Port command successful.
testuser, NLST
testuser, 150 Opening data connection for directory list.
testuser, 226 Transfer ok.
testuser, 421 Connection closed, timed out.
testuser, disconnected. (00d00:05:01)

This was without even specifying '/' in the uri when creating the FtpWebRequest object.

If you debug or browse the source code, a class called 'FtpControlStream' comes into play. See call stack:

System.dll!System.Net.FtpControlStream.BuildCommandsList(System.Net.WebRequest req) Line 555    C#
System.dll!System.Net.CommandStream.SubmitRequest(System.Net.WebRequest request = 
    {System.Net.FtpWebRequest}, bool async = false, bool readInitalResponseOnConnect = true) Line 143 C#
System.dll!System.Net.FtpWebRequest.TimedSubmitRequestHelper(bool async) Line 1122 + 0x13 bytes C#
System.dll!System.Net.FtpWebRequest.SubmitRequest(bool async = false) Line 1042 + 0xc bytes C#
System.dll!System.Net.FtpWebRequest.GetResponse() Line 649  C#

There's a method named BuildCommandsList() which is invoked. BuildCommandsList() builds a list of commands to send to the FTP server. This method has the following snippet of code:

if (m_PreviousServerPath != newServerPath) { 
    if (!m_IsRootPath
     && m_LoginState == FtpLoginState.LoggedIn
     && m_LoginDirectory != null)
    { 
     newServerPath = m_LoginDirectory+newServerPath;
    } 
    m_NewServerPath = newServerPath; 

    commandList.Add(new PipelineEntry(FormatFtpCommand("CWD", newServerPath), PipelineEntryFlags.UserCommand)); 
}

Upon the first connection to the server m_PreviousServerPath is always null, the value of newServerPath is "/" and is computed by a function named GetPathAndFileName() (invoked a few lines prior to this block of code). GetPathAndFileName() computes newServerPath as "/" if no path is supplied or if "/" is explicitly tacked on the end of the 'ftp://....' uri.

So this of course ultimately causes the CWD command to be added to the command pipeline because null != "/".

In a nutshell unfortunately you can't override this behaviour because it's burned in the source.

Hope this helps
Kev

Kev
A: 

Here is a solution: use this free, open source, FTP Client Library for C# made by Dan at C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ftpclient12062005053849am/ftpclient.aspx

Here is some example code for uploading a file:

FtpClient ftp = new FtpClient(FtpServer,FtpUserName,FtpPassword);
ftp.Login();
ftp.Upload(@"C:\image.jpg");
ftp.Close();

This library works fine out of the box, but can also easily be extended and modified.

David Grayson