FtpWebRequest返回错误550 文件不可用

31

我创建了一个小的Windows Forms应用程序,用于将文件上传到我们的一个客户FTP站点之一。但是我遇到的问题是,当我在本地计算机上运行此应用程序时,它可以成功上传文件。但是如果我在我们的服务器上运行此程序,我会收到以下错误消息:

远程服务器返回错误:(550) 文件不可用(例如,文件未找到,无法访问文件),该错误发生在代码 'objFTPRequest.GetRequestStream();'。

有人知道为什么吗?我需要配置防火墙或其他什么东西吗?以下是我的代码:

FileInfo objFile = new FileInfo(filename);
FtpWebRequest objFTPRequest;

// Create FtpWebRequest object 
objFTPRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/outbox/" + objFile.Name));

// Set Credintials
objFTPRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);

// By default KeepAlive is true, where the control connection is 
// not closed after a command is executed.
objFTPRequest.KeepAlive = false;

// Set the data transfer type.
objFTPRequest.UseBinary = true;

// Set content length
objFTPRequest.ContentLength = objFile.Length;

// Set request method
objFTPRequest.Method = WebRequestMethods.Ftp.UploadFile;

// Set buffer size
int intBufferLength = 16 * 1024;
byte[] objBuffer = new byte[intBufferLength];

// Opens a file to read
FileStream objFileStream = objFile.OpenRead();


// Get Stream of the file
Stream objStream = objFTPRequest.GetRequestStream();

int len = 0;

while ((len = objFileStream.Read(objBuffer, 0, intBufferLength)) != 0)
{
    // Write file Content 
    objStream.Write(objBuffer, 0, len);

}

            objStream.Close();
            objFileStream.Close();
16个回答

42

这个错误可能是由于多种原因引起的,比如文件不存在于服务器上、文件的安全权限等等。

首先,您需要找出错误的确切原因。 可以使用以下代码来实现:

try
{
        //Your code
}
catch(WebException e)
{
        String status = ((FtpWebResponse)e.Response).StatusDescription;
}

一旦您确定了错误的确切原因,您就可以继续解决它。

以下是一些您可以参考的链接

http://forums.asp.net/t/1777881.aspx/1

http://nickstips.wordpress.com/2010/10/25/c-ftp上传错误-远程服务器返回错误550-文件不可用-例如找不到文件-没有访问权限/

http://www.dreamincode.net/forums/topic/76361-文件上传到服务器/

http://forums.asp.net/t/1374306.aspx/1


再次您好。谢谢。实际的错误信息是550访问被拒绝。我已经给了我的文件夹完全权限,除了“特殊权限”。除了“特殊权限”之外,还有其他可能的原因吗? - chosenOne Thabs
2
大家好。我没有赢。我决定在另一台机器上托管这个应用程序。它运行良好。谢谢。 - chosenOne Thabs
如果您没有足够的权限或请求中的目录不存在,就可能会出现此错误。例如在ftp://xxx.xxx.xxx.xxx/files/中的文件。 - Mahdi Rostami
1
多么有帮助的提示,我之前只捕获了“Exception”事件,现在我可以清楚地看到错误的原因了!谢谢 - Bruno Willian

29

2
这太可怕了,但它实际上对我起作用了 - 我感到震惊,我想那应该是一个错误,但还是谢谢。 - ocramot
3
太棒了!那真的解决了这个问题。感谢你写下来。我百万年也猜不到这个答案。 - Robert4Real
也遇到了这个问题。非常好的提示,我从来没有尝试过。 - Matthias Loerke
这一定是MS FTP可执行文件中的一个错误。我看到了长文件路径推送到IIS FTP端点的连续随机故障。上述方法解决了这些问题。 - Matt
是的,就是这么简单...这种类型的错误太浪费我的时间了,但感谢您提供的好建议! - Amund Midtskog

8
我遇到了同样的问题,我所做的是:
  1. 检查操作系统是否具有写入权限。找到ftp文件夹 =>右键单击=>属性=>安全性,然后您必须知道您应该做什么。
  2. 检查ftp服务器是否向您登录的用户开放了写入权限。打开IIS=>点击ftp网站=>ftp授权规则=>添加允许规则=>选择一个用户或组以设置权限
  3. 检查ftp服务器上的目录,在第2项中执行相同的操作。
我可以使用四张图片来展示需要设置的权限: enter image description here enter image description here enter image description here enter image description here

嗨,Francis。我会尝试你的建议。我会尽快告诉你结果。谢谢。 - chosenOne Thabs
1
请记得设置子文件夹的权限。您可以在最顶层的文件夹上设置权限,并通过继承这些权限到子文件夹来实现:进入顶级FTP文件夹=>右键单击=>属性=>安全=>高级=>选择用户=>更改权限=>编辑权限(根据需要)和“包括从对象的父项继承的权限”。 - robor

4

这个可以更简单些。

我遇到了类似的问题,尝试了所有建议的解决方案,但都没有奏效。 我通过以下简单的方式弄清楚了:看一下

我的代码有误

 Dim request As Net.FtpWebRequest = CType(FtpWebRequest.Create("ftp://xxx.xxx.xxx.xxx/files"), FtpWebRequest)

在这个简单的示例中修改它:

 Dim request As Net.FtpWebRequest = CType(FtpWebRequest.Create("ftp://xxx.xxx.xxx.xxx/files/youfilename.ext"), FtpWebRequest)

接着填写请求并发送到服务器 :)

就这样。

确保服务器上的所有权限都正常工作,并且您正在使用正确的凭据。


非常敏锐!我自己也遇到了这个问题,看了这里提供的链接,但没有帮助。无论如何,评论的原因是因为官方的Microsoft文档是错误的。我按照这个例子:http://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx请求地址以“.htm”扩展名结尾,并上传了一个文本文件。我只是认为页面是一个错误而不是扩展类型。警告其他遵循上述Microsoft示例的人!问候,马特 - Matthew Blott

2
服务器通常会返回一个具有550代码的相关错误消息。但是.NET框架中的FTP实现将所有FTP状态代码转换为自己的(本地化)消息。特别是代码550被翻译为"文件不可用"。在许多情况下,这会隐藏真正的问题。
启用.NET日志以查看来自服务器的真实错误消息:
使用FtpWebRequest输出日志
以下是导致550错误的常见场景:

1
我找到了解决方案。问题在于FTP用户的当前工作目录。如果您键入类似ftp:///path/test.txt的URL,则将其用作相对路径ro工作目录。例如,CWD为/test,则使用的路径为/test/path/test.txt。如果要使用绝对路径,必须键入ftp:////path/test.txt这样的URL。然后文件将上传到文件夹/path/test.txt,没有例外。

0

请确保目标文件夹“outbox”存在。这就是我遇到550错误的问题所在。

上传之前,只需创建目标目录“output”即可。

try
        {
            WebRequest request = WebRequest.Create("ftp://" + ftpServerIP + "/outbox");
            request.Credentials = new NetworkCredential("user", "password");
            request.Method = WebRequestMethods.Ftp.MakeDirectory;
            using (var resp = (FtpWebResponse)request.GetResponse())
            {
                Console.WriteLine(resp.StatusCode);
            }
        }
        catch (WebException ex)
        {
            FtpWebResponse response = (FtpWebResponse)ex.Response;
            if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
            {
                response.Close();
                //already exists
            }
            else
            {
                response.Close();
                //doesn't exists = it's another exception
            }
        }

0
问题是你试图上传已经存在的文件或目录,这会引发一个异常,而不是一个错误。

感谢您对Stack Overflow社区做出贡献的兴趣。这个问题已经有了相当多的答案,其中一个答案已经得到社区的广泛验证。您确定您的方法之前没有被提出过吗?如果是这样的话,解释一下您的方法与众不同的地方,以及在什么情况下您的方法可能更好,并且为什么您认为之前的答案不够满意。您可以编辑您的答案并提供解释吗? - undefined

0
为了解决这个问题,需要强制 System.Net.FtpWebRequest 命令恢复到 .Net Framework 2.0/3.5 中它曾经的工作方式,并在实际命令之前发出额外的 CWD 命令。
为了做到这一点,在调用 System.Net.FtpWebRequest 类的任何实例之前,需要放置以下代码。由于它更改了整个应用程序域的设置,因此只需要调用下面的代码一次即可。
private static void SetMethodRequiresCWD()
{
        Type requestType = typeof(FtpWebRequest);
        FieldInfo methodInfoField = requestType.GetField("m_MethodInfo", BindingFlags.NonPublic | BindingFlags.Instance);
        Type methodInfoType = methodInfoField.FieldType;


        FieldInfo knownMethodsField = methodInfoType.GetField("KnownMethodInfo", BindingFlags.Static | BindingFlags.NonPublic);
        Array knownMethodsArray = (Array)knownMethodsField.GetValue(null);

        FieldInfo flagsField = methodInfoType.GetField("Flags", BindingFlags.NonPublic | BindingFlags.Instance);

        int MustChangeWorkingDirectoryToPath = 0x100;
        foreach (object knownMethod in knownMethodsArray)
        {
            int flags = (int)flagsField.GetValue(knownMethod);
            flags |= MustChangeWorkingDirectoryToPath;
            flagsField.SetValue(knownMethod, flags);
        }
 }

http://support.microsoft.com/kb/2134299


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接