F#FTP失败,C#成功 [英] F# FTP Fails where C# Succeeds

查看:153
本文介绍了F#FTP失败,C#成功的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用C#(.Net 3.5)用这段代码编写了一个应用程序。

I've an application written in C# (.Net 3.5) with this code.

using System;
using System.Net;

string strURI = String.Format("ftp://x{0}ftp/%2F'{1}'", parm1, parm2);
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(strURI);
ftp.Proxy = null;
ftp.KeepAlive = true;
ftp.UsePassive = false;
ftp.UseBinary = false;
ftp.Credentials = new NetworkCredential("uid", "pass");
ftp.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
...

我已经将它翻译成F#(.Net 4.0)在我的应用程序中。

I've translated this into F# (.Net 4.0) to use in my application.

open System.Net

let uri = sprintf "ftp://x%sftp/%%2F'%s'" parm1 parm2
let ftp = FtpWebRequest.Create(uri) :?> FtpWebRequest
ftp.Credentials <- new NetworkCredential("uid", "pass")
ftp.Method <- WebRequestMethods.Ftp.DownloadFile
ftp.Proxy <- null
let response = ftp.GetResponse() :?> FtpWebResponse
...

此时,FSI抱怨。


System.Net.WebException:远程服务器返回错误:(550)文件不可用(例如文件未找到,无法访问)。

System.Net.WebException: The remote server returned an error: (550) File unavailable (e.g. file not found, no access).

然而C#应用程序运行并成功下载文件。我在F#中丢失了什么(除了在4.0中没有的属性,即KeepAlive,UsePassive和UseBinary)?

Yet the C# application runs and successfully downloads the file. What am I missing in F# (besides the properties that aren't there in 4.0, i.e. KeepAlive, UsePassive, and UseBinary)?

推荐答案

<代码可能有错误,我现在没有F#编译器。

The code may have errors, I don't have F# compiler right now.

open System
open System.Reflection
open System.Net

let switch_to_legacy_mode _ =
  let wtype = typeof<FtpWebRequest>
  let mfield = wtype.GetField("m_MethodInfo", BindingFlags.NonPublic ||| BindingFlags.Instance)
  let mtype = mfield.FieldType
  let knfield = mtype.GetField("KnownMethodInfo", BindingFlags.Static ||| BindingFlags.NonPublic)
  let knarr = knfield.GetValue(null) :?> Array
  let flags = mtype.GetField("Flags", BindingFlags.NonPublic ||| BindingFlags.Instance)
  let flag_val = 0x100
  for f in knarr do
    let mutable ff = flags.GetValue(f) :?> int
    ff <- ff ||| flag_val
    flags.SetValue(f, ff)

let uri = sprintf "ftp://x%sftp/%%2F'%s'" parm1 parm2
do switch_to_legacy_mode () // Call it once before making first FTP request
let ftp = FtpWebRequest.Create(uri) :?> FtpWebRequest
ftp.Credentials <- new NetworkCredential("uid", "pass")
ftp.Method <- WebRequestMethods.Ftp.DownloadFile
ftp.Proxy <- null
let response = ftp.GetResponse() :?> FtpWebResponse

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


原因问题是由于.Net Framework 4中
System.Net.FtpWebRequest类的行为更改造成的。从.Net Framework $ b $对System.Net.FtpWebRequest类进行了
更改b 3.5到.Net Framework 4来简化CWD协议命令的使用。 System.Net.FtpWebRequest类的新实现
可防止在发出用户请求的实际
命令之前发送额外的CWD命令,而是直接发送
requested命令。对于完全符合RFC的FTP服务器,这应该是
不是问题,但是对于不完全符合RFC的服务器,您将
看到这些类型的错误。

The cause of this issue is due to a behavior change in the System.Net.FtpWebRequest class in .Net Framework 4. There has been a change made to the System.Net.FtpWebRequest class from .Net Framework 3.5 to .Net Framework 4 to streamline the use of the CWD protocol commands. The new implementation of the System.Net.FtpWebRequest class prevents the send of extra CWD commands before issuing the actual command which the user requested and instead directly sends the requested command. For fully RFC compliant FTP servers, this should not be an issue, however for non-fully RFC compliant servers, you will see these types of errors.

这篇关于F#FTP失败,C#成功的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆