C# FtpWebRequest类文件上载时出现550文件不可用错误。在FileZilla工作很好
我被搜索并找到了其他关于这个的问题,但没有一个解决了我的问题。我正在尝试使用示例MSDN代码通过FTP上传文件。我发现远程服务器返回了一个错误:(550)此行上的文件不可用(例如,找不到文件,无法访问)错误:ftpstream.Close() 我仔细检查了URI中是否有空格,但没有。我能够使用filezilla以相同的用户登录名完成此任务。没有一个奇怪的默认目录已经是我的URI的一部分。可以肯定的是,我正在连接到unix服务器,因此可能缺少一个设置 编辑#1(从System.Net添加错误日志)C# FtpWebRequest类文件上载时出现550文件不可用错误。在FileZilla工作很好,c#,.net,ftp,C#,.net,Ftp,我被搜索并找到了其他关于这个的问题,但没有一个解决了我的问题。我正在尝试使用示例MSDN代码通过FTP上传文件。我发现远程服务器返回了一个错误:(550)此行上的文件不可用(例如,找不到文件,无法访问)错误:ftpstream.Close() 我仔细检查了URI中是否有空格,但没有。我能够使用filezilla以相同的用户登录名完成此任务。没有一个奇怪的默认目录已经是我的URI的一部分。可以肯定的是,我正在连接到unix服务器,因此可能缺少一个设置 编辑#1(从System.Net添加错误日志)
如果没有关于错误的详细信息,很难判断,但很可能在您的路径中的某个地方缺少一个目录。如果在FTP文件路径中使用任何非标准字符,可以尝试在将其添加到Url之前对其使用 为了获得详细的故障排除信息,我在应用程序的.config文件的配置元素中添加了以下内容:
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets" maxdatasize="1024">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="System.Net.trace.log" traceOutputOptions="DateTime"/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose"/>
<!--<add name="System.Net.Sockets" value="Verbose"/>-->
</switches>
<trace autoflush="true" />
</system.diagnostics>
这就成功了。显然,CWD命令的行为在从.NET3.5迁移到4.0的过程中发生了变化 您必须首先调用此链接中的方法
我最近遇到了这个问题。它突然出现在我已经使用多年的代码上。 事实证明,我曾与许多ftp站点合作,并将相同的文件发送到所有这些ftp站点。嗯,当我访问一些ftp站点时,我被留在根目录下,但在其他站点,我立即被放在一个子目录下。 在最近的更改之前,我可以使用请求流并将文件直接放在我所在的子目录上。从上周开始,我需要完全确定路径
希望这对某人有所帮助。…此答案适用于Steen,包含与下面代码等效的PowerShell。我没有一个系统可以测试不符合要求的行为,所以您需要自己尝试
function SetMethodRequiresCWD() {
[Type] $requestType = [System.Net.FtpWebRequest]
[System.Reflection.FieldInfo] $methodInfoField = $requestType.GetField("m_MethodInfo", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance)
[Type] $methodInfoType = $methodInfoField.FieldType
[System.Reflection.FieldInfo] $knownMethodsField = $methodInfoType.GetField("KnownMethodInfo", [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)
[Array] $knownMethodsArray = [Array]$knownMethodsField.GetValue($null);
[System.Reflection.FieldInfo] $flagsField = $methodInfoType.GetField("Flags", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance)
[int] $MustChangeWorkingDirectoryToPath = 0x100
ForEach ($knownMethod In $knownMethodsArray) {
[int] $flags = [int]$flagsField.GetValue($knownMethod)
$flags = $flags -bor $MustChangeWorkingDirectoryToPath
$flagsField.SetValue($knownMethod, $flags)
}
}
您是否正在遍历任何代理?如果您使用的是powershell而不是C#,因此复制和粘贴该函数实际上是不可行的,那该怎么办?只需按您的方式抛出+1。有一个最近升级的应用程序,它在下载时运行,而不是在上传时运行。。。。。然而,在按照指示执行之后,一切都很好…@Steen我刚刚为您添加了一个答案,其中包含与SteveCalPoly的KB查找中的代码等效的PowerShell。我调用了该方法,但行“Type methodInfoType=methodInfoField.FieldType;”在我的情况下抛出了一个空指针。。。
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets" maxdatasize="1024">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="System.Net.trace.log" traceOutputOptions="DateTime"/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose"/>
<!--<add name="System.Net.Sockets" value="Verbose"/>-->
</switches>
<trace autoflush="true" />
</system.diagnostics>
private static FtpWebRequest CreateFtpWebRequest(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Credentials = new NetworkCredential(userName, password);
if (useSsl)
{
request.EnableSsl = true;
if (allowInvalidCertificate)
{
ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
}
else
{
ServicePointManager.ServerCertificateValidationCallback = null;
}
}
request.UsePassive = !useActiveFtp;
return request;
}
private static void UploadFileToServer(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, string filePath)
{
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
request.Method = WebRequestMethods.Ftp.UploadFile;
long bytesReceived = 0;
long bytesSent = 0;
using (Stream requestStream = request.GetRequestStream())
using (FileStream uploadFileStream = File.OpenRead(filePath))
{
// Note that this method call requires .NET 4.0 or higher. If using an earlier version it will need to be replaced.
uploadFileStream.CopyTo(requestStream);
bytesSent = uploadFileStream.Position;
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
bytesReceived = response.ContentLength;
}
}
function SetMethodRequiresCWD() {
[Type] $requestType = [System.Net.FtpWebRequest]
[System.Reflection.FieldInfo] $methodInfoField = $requestType.GetField("m_MethodInfo", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance)
[Type] $methodInfoType = $methodInfoField.FieldType
[System.Reflection.FieldInfo] $knownMethodsField = $methodInfoType.GetField("KnownMethodInfo", [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)
[Array] $knownMethodsArray = [Array]$knownMethodsField.GetValue($null);
[System.Reflection.FieldInfo] $flagsField = $methodInfoType.GetField("Flags", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance)
[int] $MustChangeWorkingDirectoryToPath = 0x100
ForEach ($knownMethod In $knownMethodsArray) {
[int] $flags = [int]$flagsField.GetValue($knownMethod)
$flags = $flags -bor $MustChangeWorkingDirectoryToPath
$flagsField.SetValue($knownMethod, $flags)
}
}