1

C/Sアプリケーションがあります。サーバーをAsp.NetMVC4.0で実装し、クライアントは.Net4.5で実行されます。

サーバー側にコントローラーアクションがあります。次のようになります。

public JsonResult Upload(string arg1, int arg2)
{
    //do something about arg1 and arg2 here
    ...

    var files = Request.Files;
    if (files.Count > 0)
    {
        foreach(var file in files)
        {
            var ms = new MemoryStream();
            file.InputStream.CopyTo(ms);
            //save it to somewhere
            ...
        }
    }

    ...
}

ブラウザでテストするためのテストHTMLページを作成しました。期待通りに動作しました。

クライアント側では、HttpClientクラスを使用しますが、ファイルのアップロードが必要ない場合は完全に機能しました。しかし、何日も調査した後でも、IISExpressを実行しているデバッグマシンでこれを解決することはできません。すべての手がかりがにつながることがわかりましたがMultipartFormDataContent、それらのサンプルコードをコピーしても、サーバー側はまだ何も取得できず、すべての引数は空であり、ファイルはありませんRequest.Files以前は、ファイルのアップロードに機能するHttpWebRequestに基づく独自のhttpヘルパークラスを持っていましたが、この新しいプロジェクトではHttpClientを使用することを好みます。

では、HttpClientを使用してサーバーにファイルをアップロードするにはどうすればよいですか?

4

1 に答える 1

3

Fiddlerでデバッグし、生のhttpメッセージをWinMergeと比較した後、Firefoxと私のプログラムの違いを見つけました。

Firefox(物事を単純にするためにいくつかのヘッダーを削除しました):

POST http://localhost:53400/Input/Upload HTTP/1.1
Host: localhost:53400
Content-Type: multipart/form-data; boundary=---------------------------1590871622043
Content-Length: ****

-----------------------------1590871622043
Content-Disposition: form-data; name="arg1"

abc
-----------------------------1590871622043
Content-Disposition: form-data; name="arg2"

3
-----------------------------1590871622043
Content-Disposition: form-data; name="uploadfile"; filename="wave.wav"
Content-Type: audio/wav

//file data here
-----------------------------1590871622043--

私のプログラムMultipartFormDataContent

POST http://localhost:53400/Input/Save HTTP/1.1
Content-Type: multipart/form-data; boundary="caac5ea7-8ab4-4682-be40-ecb3ddf3e70a"
Host: localhost:53400
Content-Length: ****

--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a
Content-Disposition: form-data; name=arg1

abc
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a
Content-Disposition: form-data; name=arg2

3
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a
Content-Disposition: form-data; name=uploadfile; filename=wave.wav; filename*=utf-8''wave.wav

//file data here
--caac5ea7-8ab4-4682-be40-ecb3ddf3e70a--

最後に気付くのは、これらのContent-Disposition行でFirefoxはすべての値を引用していますが、私のプログラムは引用していません。それは問題ではないと簡単に推測できますが、結局、それが正確な原因であることがわかりました。

理由がわかったので、名前を引用するのと同じくらい簡単に機能するコードを次に示します。

var multipart = new MultipartFormDataContent();
multipart.Add(new StringContent("abc"), '"' + "arg1" + '"');
multipart.Add(new StringContent("3"), '"' + "arg2" + '"');

// byte[] fileData;
multipart.Add(new ByteArrayContent(fileData), '"' + "uploadfile"+ '"', '"' + "wave.wav" + '"');
//HttpClient http; string url;
var response = await http.PostAsync(url, multipart);
response.EnsureSuccessStatusCode();
//...
于 2013-03-26T13:44:58.023 に答える