1

このコードを使用してC#(.Net 3.5)で記述されたアプリケーションがあります。

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)に変換して、アプリケーションで使用しました。

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)ファイルが利用できません(ファイルが見つからない、アクセスできないなど)。

それでも、C#アプリケーションが実行され、ファイルが正常にダウンロードされます。F#には何が欠けていますか(4.0にはないプロパティ、つまりKeepAlive、UsePassive、UseBinary以外)?

4

2 に答える 2

5

コードにエラーがある可能性があります。現在、F#コンパイラを使用していません。

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

この問題の原因は、.NetFramework4のSystem.Net.FtpWebRequestクラスの動作が変更されたことによるものです。System.Net.FtpWebRequestクラスが.NetFramework3.5から.NetFramework4に変更されました。 CWDプロトコルコマンドの使用を合理化します。System.Net.FtpWebRequestクラスの新しい実装は、ユーザーが要求した実際のコマンドを発行する前に余分なCWDコマンドの送信を防ぎ、代わりに要求されたコマンドを直接送信します。完全にRFCに準拠したFTPサーバーの場合、これは問題にはなりませんが、完全にRFCに準拠していないサーバーの場合、これらのタイプのエラーが表示されます。

于 2013-03-27T18:46:55.497 に答える
0

代わりにこれを試してください:

open System
open System.Net

let parm1 = "test"
let parm2 = "othertest"

let uri = String.Format("ftp://x{0}ftp/%2F'{1}'", parm1, parm2)
let ftp = FtpWebRequest.Create(uri) :?> FtpWebRequest;;

ダミーのparm1とparm2を追加する必要がありましたが、実際のコードでparm1とparm2が定義されていると想定しています。問題が何であれ、それはuri文字列にあると思います。つまり、uriを既知の良いuri文字列と比較することで問題が見つかると思います。

于 2013-03-27T01:09:14.500 に答える