C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: WebDAVを使ったファイルアップロードについて


(過去ログ 86 を表示中)

[トピック内 19 記事 (1 - 19 表示)]  << 0 >>

■51100 / inTopicNo.1)  WebDAVを使ったファイルアップロードについて
  
□投稿者/ 初心者 (139回)-(2010/06/24(Thu) 20:43:15)

分類:[.NET 全般] 

VC++を使って以下のプログラムを作成したいと思います。
WebDAVプロトコルを使用してURI(http;//〜)先にファイルをアップロードする。

WebDAVとは何だろうから始めてWebをいろいろと検索しています。
HTTPポートを使った通信だということは分かったのですが、通信のサンプルプログラムが見つかりません。
分かるかたがいましたらご教授をお願い致します。
引用返信 編集キー/
■51103 / inTopicNo.2)  Re[1]: WebDAVを使ったファイルアップロードについて
□投稿者/ やじゅ (1662回)-(2010/06/24(Thu) 22:59:48)
やじゅ さんの Web サイト
No51100 (初心者 さん) に返信
> VC++を使って以下のプログラムを作成したいと思います。
> WebDAVプロトコルを使用してURI(http;//〜)先にファイルをアップロードする。
>
> WebDAVとは何だろうから始めてWebをいろいろと検索しています。
> HTTPポートを使った通信だということは分かったのですが、通信のサンプルプログラムが見つかりません。
> 分かるかたがいましたらご教授をお願い致します。

CodeProjectでWEBDAVで検索してみるとか
http://www.codeproject.com/info/search.aspx?artkw=WEBDAV

How to Upload a File to a WebDAV Server in VB.NET
http://www.codeproject.com/KB/vb/WebDAV_Upload.aspx

引用返信 編集キー/
■51106 / inTopicNo.3)  Re[1]: WebDAVを使ったファイルアップロードについて
□投稿者/ れい (937回)-(2010/06/25(Fri) 01:13:50)
No51100 (初心者 さん) に返信
> VC++を使って以下のプログラムを作成したいと思います。
> WebDAVプロトコルを使用してURI(http;//〜)先にファイルをアップロードする。
>
> WebDAVとは何だろうから始めてWebをいろいろと検索しています。
> HTTPポートを使った通信だということは分かったのですが、通信のサンプルプログラムが見つかりません。
> 分かるかたがいましたらご教授をお願い致します。

WebDAVはHTTPの拡張プロトコルです。
アップロードはHTTPで規定されたPUTを用います。

#Ifヘッダーなどの拡張が定義されていますが、使わなくても問題ありません。

ですので、WebDAVによるアップロードのサンプル、というものはあまりないと思います。
HTTPによるアップロードのサンプルとか、
PUTメソッドのサンプルプログラムを探すとよいと思います。

引用返信 編集キー/
■51110 / inTopicNo.4)  Re[2]: WebDAVを使ったファイルアップロードについて
□投稿者/ todo (16回)-(2010/06/25(Fri) 09:35:58)
>WebDAVとは何だろうから始めてWebをいろいろと検索しています。

まずは環境を作って触ってみましょう。

IISのWebDAVを有効にする
http://www.atmarkit.co.jp/fwin2k/win2ktips/546iis6func/iis6func.html

WebDAVでファイルを共有する
http://www.apec.aichi-c.ed.jp/project/joho/kanri/win2000/WebDAV.htm
引用返信 編集キー/
■51152 / inTopicNo.5)  Re[3]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (140回)-(2010/06/25(Fri) 20:11:20)
みなさまありがとうございます。
まずはリンク先を拝見させていただきます。

>HTTPによるアップロードのサンプルとか、
>PUTメソッドのサンプルプログラムを探すとよいと思います。
ありがとうございます。
こちらも調べてみます。
引用返信 編集キー/
■51188 / inTopicNo.6)  Re[4]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (141回)-(2010/06/27(Sun) 04:04:24)
IISでWebDAV環境を作り、いろいろ試した結果cltを使用して無事ファイルのアップロードは行えました。
レスポンス結果の何をもってアップロードが正常に行えたかを判断するかまだ調査中ですが・・・
レスをくれたみなさまありがとうございました。

以下サンプルです。
↓dllのインポート及びネームスペース
#using <System.dll>
using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Net;
using namespace System::Text;

↓処理コード

//URI先への接続準備
WebRequest^ webReq = WebRequest::Create( "http://localhost/Webdav/test.txt" );
//ユーザーとパスが設定されている場合
//webReq.Credentials = new NetworkCredential("USERNAME", "PASSWORD");
webReq->Method = WebRequestMethods::File::UploadFile;

//コピー元のストリーム作成
System::String^ path = _T("c:\\tmp\\test.txt");
FileStream^ inStrm = File::OpenRead( path );
webReq->ContentLength = inStrm->Length;

// ファイルをバッファに読み込み・サーバーへ書き込み
Stream^ outStrm = webReq->GetRequestStream();
int bufSize = 1048576; // 1MB
array<Byte> ^ buffer = gcnew array<Byte>(1048576);
int bytesRead = 0;

//データの書き込み
while ((bytesRead = inStrm->Read(buffer, 0, bufSize)) > 0){
outStrm->Write(buffer, 0, bytesRead);
}

//フラッシュ
outStrm->Flush();

//ストリームのクローズ
inStrm->Close();
outStrm->Close();


// 結果取得
HttpWebResponse^ res = dynamic_cast<HttpWebResponse^>(webReq->GetResponse());
//レスポンスからファイルが正常にアップロードできたかを確認する

//レスポンスのクローズ
res->Close();
解決済み
引用返信 編集キー/
■51191 / inTopicNo.7)  Re[5]: WebDAVを使ったファイルアップロードについて
□投稿者/ ちゃっぴ (28回)-(2010/06/27(Sun) 06:58:24)
ちゃっぴ さんの Web サイト
途中で例外が発生した場合も考慮して、Close() ではなくて using statement 使った解放にしておいた方がいいと思いますよ。
解決済み
引用返信 編集キー/
■51194 / inTopicNo.8)  Re[5]: WebDAVを使ったファイルアップロードについて
□投稿者/ れい (938回)-(2010/06/27(Sun) 09:39:16)
No51188 (初心者 さん) に返信
> webReq->Method = WebRequestMethods::File::UploadFile;

中身同じなので別に構わないのですが、
WebRequestMethods::Http::Put
こちらの方がより適切でしょう。

> //フラッシュ
> outStrm->Flush();

無駄にflushする必要はありません。

> HttpWebResponse^ res = dynamic_cast<HttpWebResponse^>(webReq->GetResponse());
> //レスポンスからファイルが正常にアップロードできたかを確認する

WebRequest系の操作が正常に動いていない場合、

1 GetRequestStreamで得たStreamへWriteしたときに例外を吐く場合
2 GetResponseで例外を吐き、WebResponseが手に入らない場合と、
3 WebResponseは帰ってくるが内部にエラーコードを持つ場合、
4 GetResponseStreamでストリームが得るときに例外を吐く場合、
5 GetResponseStreamでえたStreamから読むときに例外を吐く場合、

の5通りがあります。

3に関しては例外を吐かないので自分で検査する必要があります。
Httpの場合、基本的には200番代のレスポンスが帰ってくれば正常ですので、
HttpWebRequest.StatusCodeを検査して200以上300未満であれば正常です。
それ以外の場合は自分で対処しなければなりません。
引用返信 編集キー/
■51195 / inTopicNo.9)  Re[6]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (142回)-(2010/06/27(Sun) 09:54:23)
2010/06/27(Sun) 10:01:39 編集(投稿者)

No51191 (ちゃっぴ さん) に返信
> 途中で例外が発生した場合も考慮して、Close() ではなくて using statement 使った解放にしておいた方がいいと思いますよ。
try〜catchでその辺りは対応しようかと考えていました。
usingステートメントというのがあるのですね
自動でクローズをしてくれるのは便利ですね
始めて聞いた言葉で使い方がよく分からないのですが、以下のようにストリームを開くたびにusingを呼べばいいのでしょうか?

//URI先への接続準備
WebRequest^ webReq = WebRequest::Create( "http://localhost/Webdav/test.txt" );
//ユーザーとパスが設定されている場合
//webReq.Credentials = new NetworkCredential("USERNAME", "PASSWORD");
webReq->Method = WebRequestMethods::File::UploadFile;

//コピー元のストリーム作成
System::String^ path = _T("c:\\tmp\\test.txt");
using (FileStream^ inStrm = File::OpenRead( path )){
  webReq->ContentLength = inStrm->Length;

  // ファイルをバッファに読み込み・サーバーへ書き込み
  using (Stream^ outStrm = webReq->GetRequestStream()){
    int bufSize = 1048576; // 1MB
    array<Byte> ^ buffer = gcnew array<Byte>(1048576);
    int bytesRead = 0;

    //データの書き込み
    while ((bytesRead = inStrm->Read(buffer, 0, bufSize)) > 0){
      outStrm->Write(buffer, 0, bytesRead);
    }

    //フラッシュ
    outStrm->Flush();
  }//outStrmのクローズ
}//inStrmのクローズ

// 結果取得
using (HttpWebResponse^ res = dynamic_cast<HttpWebResponse^>(webReq->GetResponse()){
  //レスポンスからファイルが正常にアップロードできたかを確認する
}//レスポンスのクローズ
解決済み
引用返信 編集キー/
■51196 / inTopicNo.10)  Re[6]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (143回)-(2010/06/27(Sun) 09:58:16)
No51194 (れい さん) に返信
丁寧な説明ありがとうございます。
勉強になります。
特にWebRequest系の説明がとても助かります!


> ■No51188 (初心者 さん) に返信
>> webReq->Method = WebRequestMethods::File::UploadFile;
>
> 中身同じなので別に構わないのですが、
> WebRequestMethods::Http::Put
> こちらの方がより適切でしょう。
>
>> //フラッシュ
>> outStrm->Flush();
>
> 無駄にflushする必要はありません。
>
>> HttpWebResponse^ res = dynamic_cast<HttpWebResponse^>(webReq->GetResponse());
>> //レスポンスからファイルが正常にアップロードできたかを確認する
>
> WebRequest系の操作が正常に動いていない場合、
>
> 1 GetRequestStreamで得たStreamへWriteしたときに例外を吐く場合
> 2 GetResponseで例外を吐き、WebResponseが手に入らない場合と、
> 3 WebResponseは帰ってくるが内部にエラーコードを持つ場合、
> 4 GetResponseStreamでストリームが得るときに例外を吐く場合、
> 5 GetResponseStreamでえたStreamから読むときに例外を吐く場合、
>
> の5通りがあります。
>
> 3に関しては例外を吐かないので自分で検査する必要があります。
> Httpの場合、基本的には200番代のレスポンスが帰ってくれば正常ですので、
> HttpWebRequest.StatusCodeを検査して200以上300未満であれば正常です。
> それ以外の場合は自分で対処しなければなりません。
解決済み
引用返信 編集キー/
■51200 / inTopicNo.11)  Re[7]: WebDAVを使ったファイルアップロードについて
□投稿者/ ちゃっぴ (29回)-(2010/06/27(Sun) 13:24:35)
ちゃっぴ さんの Web サイト
> 始めて聞いた言葉で使い方がよく分からないのですが、以下のようにストリームを開くたびにusingを呼べばいいのでしょうか?

おおむねそんな感じで良いと思います。ただ、個人的には下記の対応行うかなぁ。

・ FileStream は File::OpenRead() を利用せず、constructor を使って初期化し参照ではなく実体を変数にする
これを行うことにより using の利用を減らせます。
参照で無ければ scope 抜けたときに destructor 呼ばれることが保証されますので。
FileStream fileStream(path, FileMode::Open);

・ WebRequest は HttpWebRequest に cast して使う
HTTP header を弄ること間々あるので。

・ Flush() は呼び出さない
れいさんも書かれていますが、delete 呼ばれるときに自動的に Flush() が呼ばれるので不要です。

・ WebRequestMethods::Http::Put を利用する
れいさんが書かれていることに同じ。

まあ、上記対応しなくても問題なく動作するでしょうからどちらでもよいですけど。

> 3に関しては例外を吐かないので自分で検査する必要があります。
> Httpの場合、基本的には200番代のレスポンスが帰ってくれば正常ですので、
> HttpWebRequest.StatusCodeを検査して200以上300未満であれば正常です。
> それ以外の場合は自分で対処しなければなりません。

Status code 400 系および 500 系の多くは例外が発生したと記憶していますけど。
もっとも、すべての status code を検証したわけではないので私でも status code が問題ないかの確認は入れますね。

あと、C++/CLI (.NET Framework) で行っているようですが問題無いんですかね?
利用環境の制約や performance とかで問題無いのであれば私もこちらでやりますけど。
というか C# で書いてしまうと思います。
もし、native でやるとするなら MSXML::IXMLHTTPRequest あたりを使うことになりますかね。
引用返信 編集キー/
■51201 / inTopicNo.12)  Re[8]: WebDAVを使ったファイルアップロードについて
□投稿者/ ちゃっぴ (30回)-(2010/06/27(Sun) 14:05:57)
ちゃっぴ さんの Web サイト
あと気づいちゃったんですが、comment out されているとはいえ、これ変ですね。

//webReq.Credentials = new NetworkCredential("USERNAME", "PASSWORD");

new → gcnew

それからこれちょっと気持ち悪いかも。

while ((bytesRead = inStrm->Read(buffer, 0, bufSize)) > 0) {}

Stream::Read() の戻り値を再利用しないなら

while (inStrm->Read(buffer, 0, bufSize) > 0) {}

でいいんじゃないかと。
解決済み
引用返信 編集キー/
■51202 / inTopicNo.13)  Re[8]: WebDAVを使ったファイルアップロードについて
□投稿者/ れい (939回)-(2010/06/27(Sun) 14:23:31)
No51196 (初心者 さん) に返信
> 特にWebRequest系の説明がとても助かります!

助かるということなのでもう少し追加を。

No51200 (ちゃっぴ さん) に返信
>>3に関しては例外を吐かないので自分で検査する必要があります。
>>Httpの場合、基本的には200番代のレスポンスが帰ってくれば正常ですので、
>>HttpWebRequest.StatusCodeを検査して200以上300未満であれば正常です。
>>それ以外の場合は自分で対処しなければなりません。
>
> Status code 400 系および 500 系の多くは例外が発生したと記憶していますけど。
> もっとも、すべての status code を検証したわけではないので私でも status code が問題ないかの確認は入れますね。

WebRequestのプロパティ次第で400、500のいくつかは例外を投げずに戻ったと思います。
AllowAutoRedirectがfalseになっていたり、リダイレクトされまくると300代も発生します。

HttpWebRequestに少しバグがあり、
リダイレクトされていたりすると正常にアップロードされなくても正常に戻ったり、
その逆があったりしますので、StatusCodeの確認は必須です。

WebExceotionが投げられた場合、WebException.StatusがProtocolErrorになります。
WebException.StatusがProtocolErrorの場合、
WebException.ResponseにHttpWebResponseが入るのでそこからいろいろ取得できます。
StatusCodeとかサーバーのメッセージとか。

それと、認証ありのPUTの場合、
ほとんどのケースで、認証のために余計なトラフィックが発生します。
BASIC認証でよいのであれば、HttpWebRequest.PreAuthenticateをtrueとしておくとうまくいきます。

巨大なファイルの場合はAllowWriteStreamBufferingをfalseにしないとうまくいきません。
その場合、リダイレクトや認証があるといろいろ面倒なことになります。

引用返信 編集キー/
■51204 / inTopicNo.14)  Re[8]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (144回)-(2010/06/27(Sun) 18:51:02)
No51200 (ちゃっぴ さん) に返信
> ・ FileStream は File::OpenRead() を利用せず、constructor を使って初期化し参照ではなく実体を変数にする
> これを行うことにより using の利用を減らせます。
> 参照で無ければ scope 抜けたときに destructor 呼ばれることが保証されますので。
> FileStream fileStream(path, FileMode::Open);
>
> ・ WebRequest は HttpWebRequest に cast して使う
> HTTP header を弄ること間々あるので。
>
> ・ Flush() は呼び出さない
> れいさんも書かれていますが、delete 呼ばれるときに自動的に Flush() が呼ばれるので不要です。
このようなテクニックもあるのですね。
勉強になります!

> Status code 400 系および 500 系の多くは例外が発生したと記憶していますけど。
> もっとも、すべての status code を検証したわけではないので私でも status code が問題ないかの確認は入れますね。
status codeが200以上300未満を正常としてとりあえず実装中です。


> あと、C++/CLI (.NET Framework) で行っているようですが問題無いんですかね?
> 利用環境の制約や performance とかで問題無いのであれば私もこちらでやりますけど。
> というか C# で書いてしまうと思います。
> もし、native でやるとするなら MSXML::IXMLHTTPRequest あたりを使うことになりますかね。
他と比べたわけではないですが、若干時間がかかってる気がします。
環境はIISのWebDAV構成で、閉じた世界でやるようです。
サンプルを探しててもC#ばかりでしたので、本当はC#がいいのかもしれませんが、Cでやって欲しいとの要望でしたので・・・

引用返信 編集キー/
■51205 / inTopicNo.15)  Re[9]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (145回)-(2010/06/27(Sun) 18:54:54)
No51201 (ちゃっぴ さん) に返信
> あと気づいちゃったんですが、comment out されているとはいえ、これ変ですね。
>
> //webReq.Credentials = new NetworkCredential("USERNAME", "PASSWORD");
>
> new → gcnew

おっしゃるとおりです。
C#のサンプルを持ってきていじっていたのでそのときの名残です。
今回はユーザーもパスワードも設定していない環境で試していたため、コメントのまま放置していました。

> それからこれちょっと気持ち悪いかも。
>
> while ((bytesRead = inStrm->Read(buffer, 0, bufSize)) > 0) {}
>
> Stream::Read() の戻り値を再利用しないなら
>
> while (inStrm->Read(buffer, 0, bufSize) > 0) {}
>
> でいいんじゃないかと。

そのとおりだと思います。
デバッグでデータ取得してるよねという確認で入れていました。

多数のご指摘、アドバイス感謝です!
解決済み
引用返信 編集キー/
■51206 / inTopicNo.16)  Re[9]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (146回)-(2010/06/27(Sun) 19:05:21)
No51202 (れい さん) に返信

> WebRequestのプロパティ次第で400、500のいくつかは例外を投げずに戻ったと思います。
> AllowAutoRedirectがfalseになっていたり、リダイレクトされまくると300代も発生します。
>
> HttpWebRequestに少しバグがあり、
> リダイレクトされていたりすると正常にアップロードされなくても正常に戻ったり、
> その逆があったりしますので、StatusCodeの確認は必須です。
>
> WebExceotionが投げられた場合、WebException.StatusがProtocolErrorになります。
> WebException.StatusがProtocolErrorの場合、
> WebException.ResponseにHttpWebResponseが入るのでそこからいろいろ取得できます。
> StatusCodeとかサーバーのメッセージとか。
なるほど。
例外処理のログに情報を埋め込むんだほうがいいですね。



> それと、認証ありのPUTの場合、
> ほとんどのケースで、認証のために余計なトラフィックが発生します。
> BASIC認証でよいのであれば、HttpWebRequest.PreAuthenticateをtrueとしておくとうまくいきます。
>
> 巨大なファイルの場合はAllowWriteStreamBufferingをfalseにしないとうまくいきません。
> その場合、リダイレクトや認証があるといろいろ面倒なことになります。
今のところ1ファイルあたり1Mを越えることはない予定ですが、認証も含め確認しておきます。
WEBシステムは、今回がほとんど初めての手探り状態(相手側も)なので、こういったアドバイスはすごく助かります!

お勧めの書籍かサイトがあれば教えていただけないでしょうか?
解決済み
引用返信 編集キー/
■51216 / inTopicNo.17)  Re[10]: WebDAVを使ったファイルアップロードについて
□投稿者/ れい (940回)-(2010/06/28(Mon) 08:54:31)
No51206 (初心者 さん) に返信
> お勧めの書籍かサイトがあれば教えていただけないでしょうか?

オススメの書籍はありません。
オススメのサイトはココ。http://bbs.wankuma.com/

ここ3年ほどずっと漁ってますが、
WebRequest、特にHttpWebRequestの動作の詳細を正しく的確にまとめた情報は一つも見つけられていません。

ココなら質問すれば誰か答えてくれるかと。
引用返信 編集キー/
■51223 / inTopicNo.18)  Re[9]: WebDAVを使ったファイルアップロードについて
□投稿者/ ちゃっぴ (31回)-(2010/06/28(Mon) 11:47:28)
ちゃっぴ さんの Web サイト
> お勧めの書籍かサイトがあれば教えていただけないでしょうか?

無いですね。MSDN を頼りにひたすら debug を繰り返すしか。

やる気がある方のようなのでもう一つ tips をば。

方法 : ネットワーク トレースを構成する
http://msdn.microsoft.com/en-us/library/ty48b824.aspx

開発時はこれを configuation file に加えておくと良いです。
Network trace を取得できるので開発時に大いに役立つでしょう。特に SSL 利用時。
Release 時には comment out してね。
引用返信 編集キー/
■51274 / inTopicNo.19)  Re[10]: WebDAVを使ったファイルアップロードについて
□投稿者/ 初心者 (149回)-(2010/06/30(Wed) 10:47:34)
れい様、ちゃっぴ様、たくさんの助言ありがとうございました!
またお世話になるかもしれませんが、動かしながら試行錯誤してみます。

No51223 (ちゃっぴ さん) に返信
>>お勧めの書籍かサイトがあれば教えていただけないでしょうか?
>
> 無いですね。MSDN を頼りにひたすら debug を繰り返すしか。
>
> やる気がある方のようなのでもう一つ tips をば。
>
> 方法 : ネットワーク トレースを構成する
> http://msdn.microsoft.com/en-us/library/ty48b824.aspx
>
> 開発時はこれを configuation file に加えておくと良いです。
> Network trace を取得できるので開発時に大いに役立つでしょう。特に SSL 利用時。
> Release 時には comment out してね。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -