550 file unavailable error with FtpWebRequest class file upload. Works fine in FileZilla

前端 未结 4 595
借酒劲吻你
借酒劲吻你 2021-01-13 08:26

I\'m searched and found other questions on this but none have solved my issues. I\'m trying to upload a file via FTP using sample MSDN code. I get the The remote server retu

相关标签:
4条回答
  • 2021-01-13 09:07

    This answer is for Steen and contains a PowerShell equivalent to the code in http://support.microsoft.com/kb/2134299 below. I don't have a system that has the non-compliant behavior to test against so you'll need to try it yourself.

    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)
        }
    }
    
    0 讨论(0)
  • 2021-01-13 09:09

    It's difficult to tell without detailed information about the error, but it seems most likely that somewhere in your path there's a directory missing. One thing to try if you use any non-standard characters in your FTP file path is to use HttpUtility.UrlPathEncode on it prior to adding it to the Url.

    To get detailed troubleshooting information, I add the following inside the configuration element of my application's .config file:

    <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>
    

    Also, just for reference, here's the code I use for uploads:

        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;
            }
        }
    
    0 讨论(0)
  • 2021-01-13 09:12

    This did the trick. apparently the CWD command behavior changed in the move from .NET 3.5 to 4.0.

    You have to first call the method in this link.

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

    0 讨论(0)
  • 2021-01-13 09:21

    I had this problem just recently. It just popped on code that I had been using for years. It turned out that I had been working with a number of ftp sites and was sending the same files to all these ftp sites. Well, when I went to some ftp sites, I was left at root, but at others, i was immediately put on a subdirectory. Before this recent change I could use request stream and put the file directly on the subdirectly where I was put. As of last week I needed to fully qualify the path.

    Hope this helps someone.....

    0 讨论(0)
提交回复
热议问题