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

わんくま同盟

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

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


(過去ログ 126 を表示中)
■74873 / )  Re[4]: WebDAVサーバーファイルアップロードのエラー
□投稿者/ れい (4回)-(2015/02/04(Wed) 22:45:11)
No74871 (DSC渡邊 さん) に返信
> 大きなデータをアップロードする際の注意点について書かれたURLを見つけて、そこには「AlowWriteStreamBuffering プロパティに Falseを設定して認証機能と共に利用すると 「この要求には、データのバッファが必要です」というエラーが発生する 」と書かれていましたが…

それは認証方式、AllowAutoRedirect、ContentLength、SendChunked等の設定によります。
プロトコル上、「長さ」の送信が必要になる場合と「再送」する可能性がある場合にバッファリングが必要になります。

> 結局、何が原因でアップロードエラーが発生したのか、はっきりしませんでした。

認証方式を書いていないのでわかりませんが、
設定を一切いじっていないということであればNTLMかKerberos等の接続指向の認証プロトコルを使っていたのではないですか?
通常HTTPはリクエスト毎に認証しますが、これらはTCP接続単位で認証するため、他の接続の影響を受けます。

認証用の空PUTはRFCに軽く述べられていますが、"Allow: PUT"とヘッダーを送り、書き込みたいURLと同じURLを使うべきです。
また、リダイレクトが発生することも考慮し、2回目のPUTではURLを書き換えておかなければなりません。
サーバーによってはセッションを保持しなければいけない場合もあります。
その他いくつかオマジナイを入れ、下記のようなコードがよいでしょう。(動作未確認ですが。

        Dim fileToUpload As String 
        Dim fileLength As Long 
        Dim url As Uri
        Dim nc As New NetworkCredential(ユーザー名, パスワード)
        Dim cc As New CookieContainer 'for tracking session
        Dim request As HttpWebRequest
        '空ファイルPUT
        fileToUpload = アップロードしたい大容量ファイルのフルパス
        Using fs As New IO.FileStream(fileToUpload, IO.FileMode.Open, IO.FileAccess.Read)
            fileLength = fs.Length
            url = New Uri(サーバーのURL, "/" & サーバーのアップロード先フォルダ & IO.Path.GetFileName(fileToUpload))

            request = DirectCast(System.Net.HttpWebRequest.Create(url), HttpWebRequest)
            request.Method = WebRequestMethods.Http.Put
            request.UnsafeAuthenticatedConnectionSharing = True 'for Nego/NTLM/Kerberos
            request.KeepAlive = True
            request.Headers.Add(HttpRequestHeader.Allow, "PUT") ' for EmptyPUT
            request.AllowWriteStreamBuffering = True
            request.PreAuthenticate = True
            request.Headers.Add("Translate: f") ' for IIS
            request.Credentials = nc
            request.CookieContainer = cc
            Using res As HttpWebResponse = request.GetResponse()
                url = res.ResponseUri
            End Using

            request = DirectCast(System.Net.HttpWebRequest.Create(url), HttpWebRequest)
            request.Method = WebRequestMethods.Http.Put
            request.UnsafeAuthenticatedConnectionSharing = True
            request.KeepAlive = True
            request.ContentLength = fileLength
            request.SendChunked = True
            request.AllowWriteStreamBuffering = False 'no-buffering
            request.PreAuthenticate = True ' for sharing auth info
            request.AllowAutoRedirect = False
            request.Headers.Add("Translate: f")
            request.Credentials = nc
            request.CookieContainer = cc

            Using reqst As IO.Stream = request.GetRequestStream()
                Dim buf As Byte() = New Byte(64 * 1024 - 1) {}
                Dim r As Byte
                While True
                    r = fs.Read(buf, 0, buf.Length)
                    If r = 0 Then Exit While
                    reqst.Write(buf, 0, r)
                End While
            End Using
        End Using

        Dim code As HttpStatusCode
        Using response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
            code = response.StatusCode
            If code >= 300 AndAlso code < 400 Then Throw New Exception
        End Using

返信 編集キー/


管理者用

- Child Tree -