質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
FTP

FTP(File Transfer Protocol)は、ネットワークでのファイル転送を行うための通信プロトコルの1つである。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

5628閲覧

C# FtpWebRequest.GetResponse のエラー

zz123

総合スコア6

FTP

FTP(File Transfer Protocol)は、ネットワークでのファイル転送を行うための通信プロトコルの1つである。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/07/18 13:08

##前提・実現したいこと
あるFTPサーバーのディレクトリ /aa/bb/cc に FtpWebRequest.GetResponse でアクセスすると
WebException が発生します。しかしコマンドプロンプトからFTPコマンドではアクセス可能です。
FtpWebRequest でアクセスを成功させたい、またはアクセスできない理由を明確にしたいです。

実行環境は Windows Server 2008 R2 です。
管理者は別会社の方で、私はFTPサーバー設定には全く詳しくないです。

##ソースコードとエラー

C#

1 void test(string user, string pass, string uri) 2 { 3 NetworkCredential credential = new NetworkCredential(user, pass); 4 FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(uri); 5 req.Proxy = null; 6 req.Credentials = this.credential; 7 req.Method = WebRequestMethods.Ftp.ListDirectory; 8 FtpWebResponse ftpRes = null; 9 try 10 { 11 ftpRes = (FtpWebResponse)req.GetResponse(); 12 } 13 catch (WebException e) 14 { 15 if (ftpRes == null) 16 { 17 Console.WriteLine("エラー"); 18 throw; 19 } 20 } 21 finally 22 { 23 if (ftpRes != null) 24 { 25 ftpRes.Close(); 26 } 27 } 28 }

例外発生時、ftpRes は null が入っています。例外メッセージは↓のようなものです。
「System.Net.WebException: リモート サーバーがエラーを返しました: (550) ファイルが使用できません (例: ファイルが見つからない、ファイルへのアクセスがない)」

##試したこと
uri = /aa/bb/cc へのアクセスは上記のように失敗しますが、1つ下のディレクトリ
uri = /aa/bb/cc/dd へのアクセス、アップロードは成功します。
このとき、user, pass は同じものを使っています。

また、コマンドプロンプトから ftp コマンドを使用すると(上記と同じ user, pass)、
/aa/bb/cc, aa/bb/cc/dd どちらのディレクトリにもアクセス、アップロードが成功します。

恐らくディレクトリのアクセス権限だと思い、コマンドプロンプトで ls -l を実行すると、
どちらも同様でした。

  • /aa/bb/cc への ls -l 結果

  drwxrwxr-x 469 user pass 125440 7月 18日 13:57 cc

  • /aa/bb/cc/dd への ls -l 結果

  drwxrwxr-x 2 user pass 512 4月 24日 2019年 dd

プログラムの修正で FtpWebRequest.GetResponse でアクセス成功させる方法があるでしょうか。
もしくは現状で失敗する理由を判断する方法があるでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zz123

2020/07/19 01:50

ありがとうございます。Response = null です。 ToString() で表示すると以下のようなメッセージが出力されるのですが、これを見てもよく分からないです。 Response が null になるのはどのような原因が考えられるでしょうか。 System.Net.WebException: リモート サーバーがエラーを返しました: (550) ファイルが使用できません (例: ファイルが見つからない、ファイルへのアクセスがない) 場所 System.Net.FtpWebRequest.SyncRequestCallback(Object obj) 場所 System.Net.CommandStream.Dispose(Boolean disposing) 場所 System.IO.Stream.Close() 場所 System.Net.ConnectionPool.Destroy(PooledStream pooledStream) 場所 System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse) 場所 System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage) 場所 System.Net.FtpWebRequest.GetResponse() 場所 FtpAdapter.IsDirExist(String uri) 場所 d:\test\src\ExCommon\Util\FtpAdapter.cs:行 456
KOZ6.0

2020/07/19 16:24

また聞きの話で申し訳ないですが、ftp で接続したとき PWD コマンドは実行できるでしょうか? 以前同様の話があって、ftp サーバー側で PWD コマンドの実行が禁止されていたらしいです。 残念ながら抑止することができなかったので wininet を使ったようです。
zz123

2020/07/19 23:59

すみません、現地作業者が現場を離れたため確認できなくなってしまいました。 FTPサーバー側設定によってはそのような設定ができるんですね。
guest

回答1

0

自己解決

実運用が始まってしまったため、調査修正ができなくなってしまいました。
結局 ftpRes=null の場合でも処理終了しないようにして続行(ディレクトリ作成処理)することで、状況が改善しました。

よくよく確認したら、存在するディレクトリ /aa/bb/cc/ に対してではなく、存在しないディレクトリ /aa/bb/cc/xx に対して FtpWebRequest.GetResponse を行っていました。なので↑で説明している前提からして間違っていました。申し訳ありません。

この場合でも ftpRes = null にはならないと思っていたのですが、特にそのようなことはドキュメントに記述されていないですね。
SHOMI様ご指摘のように例外の Response, Status を確認すれば恐らく内容が分かったはずだと今になって気づきました。
Response, Status を(例外ではなく) ftpRes のプロパティと思い込んでいたため、ただ例外メッセージだけ見て「解らんなあ」とほざいておりました。
お恥ずかしい話で大反省しております。

例外の内容が確認できないのが心残りですが、とりあえず本件クローズとします。お手数おかけしました。

投稿2020/07/20 00:09

zz123

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問