8


1

.NETを使用してファイルをサーバーHttpWebRequestまたはWebClientに投稿する

さて、ここに取引があります。 質問が述べているように、私はファイルをウェブサーバーにPOSTしようとしていますが、いくつかの問題があります。

Curl.exeを使用してこの同じファイルを同じWebサーバーに投稿しようとしましたが、問題はありませんでした。 curlで使用したフラグは、.NETクラスで問題が発生する潜在的な理由を指摘する可能性がある場合に備えて投稿しました。

curl.exe --user "myUser:myPass" --header "Content-Type: application/gzip"
--data-binary "@filename.txt.gz" --cookie "data=service; data-ver=2; date=20100212;
time=0900; location=1234" --output "out.txt" --dump-header "header.txt"
http://mysite/receive

WebClientやHttpWebRequestなどの.NETクラスを使用して同じことをしようとしています。 これが私が試したコードのサンプルです。 WebClientでは505 HTTP Version Not Supportedエラーが表示され、HttpWebRequestでは501 Not Implementedが表示されます。

WebClientで試す場合:

public void sendFileClient(string path){
    string url = "http://mysite/receive";
    WebClient wc = new WebClient();
    string USERNAME = "myUser";
    string PSSWD = "myPass";

    NetworkCredential creds = new NetworkCredential(USERNAME, PSSWD);
    wc.Credentials = creds;
    wc.Headers.Set(HttpRequestHeader.ContentType, "application/gzip");
    wc.Headers.Set("Cookie", "location=1234; date=20100226; time=1630; data=service; data-ver=2");

    wc.UploadFile(url, "POST", path);
}

そして、HttpRequestを使用している間:

public Stream sendFile(string path)
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://myserver/receive");
    string USERNAME = "myUser";
    string PSSWD = "myPass";
    NetworkCredential creds = new NetworkCredential(USERNAME, PSSWD);
    request.Credentials = creds;
    request.Method = "POST";
    request.ContentType = "application/gzip";
    request.Headers.Set("Cookie", "location=1234; date=20100226; time=1630; data=service; data-ver=2");
    FileInfo fInfo = new FileInfo(path);
    long numBytes = fInfo.Length;
    FileStream fStream = new FileStream(path, FileMode.Open, FileAccess.Read);
    BinaryReader br = new BinaryReader(fStream);
    byte[] data = br.ReadBytes((int)numBytes);
    br.Close();
    fStream.Close();
    fStream.Dispose();
    Stream wrStream = request.GetRequestStream();
    BinaryWriter bw = new BinaryWriter(wrStream);
    bw.Write(data);
    bw.Close();
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    return response.GetResponseStream();
}

2 Answer


10


まず、フィドラーのようなものを使用し、リクエストと応答を調べてcurlとSystem.Net.WebClientの違いを確認します。

また、試してみることができます(ただし、デバッグプロキシで検査すると、違いを特定できます)。

資格情報キャッシュを使用して、基本認証の資格情報を設定します。

var cc= new CredentialCache();
cc.Add(new Uri(url),
                  "Basic",
                  new NetworkCredential("USERNAME", "PASSWORD"));
wc.Credentials = cc;

ユーザーエージェントヘッダーを設定します。

string _UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
wc.Headers.Add(HttpRequestHeader.UserAgent, _UserAgent);

WebRequestのプロトコルバージョンを変更します。

reqeust.KeepAlive = false;
request.ProtocolVersion=HttpVersion.Version10;


1


501が一致する場合、さらに2つの理由があるかもしれません。

----------1---------

ポストデートに中国語の文字またはその他の文字が含まれている場合。 e.g.

postDate = "type=user&username=计算机学院&password=123&Submit=+登录+"

正しいメッセージを投稿するには、次の2行を追加することもできます。

Request.SendChunked = true;
Request.TransferEncoding = "GB2312";

これも501につながります。

その場合、2行を削除し、postDateをそのように変更できます。

postDate = "type=user&username=%BC%C6%CB%E3%BB%FA%D1%A7%D4%BA&password=123&Submit=+%C8%B7%C8%CF+"

たぶん、これはpostDateを修正するソリューションですが、まだテストしていません。

string str = Encoding.GetEncoding("gb2312").GetString(tmpBytes);

----------2---------

Response.StatusCode == HttpStatusCode.Redirect Redirectが302に等しい場合。 次の行は必須です:

Request.AllowAutoRedirect = false;