使用.NET将文件发布到服务器HttpWebRequest或WebClient
好的,这是交易。正如问题所述,我试图将文件发布到网络服务器,并且遇到了一些问题。使用.NET将文件发布到服务器HttpWebRequest或WebClient
我试过把这个文件发布到使用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
我试图使用.NET类像WebClient或HttpWebRequest做同样的事情。这是我试过的代码的一个例子。使用WebClient,我得到一个505 HTTP版本不支持的错误,并且使用HttpWebRequest,我得到了501未实现。
当使用Web客户端尝试它:
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();
}
首先,使用这样的小提琴手和检查请求和响应,看袅袅之间有什么不同和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;
“更改WebRequest上的协议版本”诀窍! – Myishmael 2010-03-02 13:28:27
类似问题:添加一个用户代理标题为我修复了它。 – 2011-06-29 15:09:29
501协议可能还有另外两个原因。
---------- --------- 1
当踵包含一些中国Chracter或其它字符。 例如
postDate = "type=user&username=计算机学院&password=123&Submit=+登录+"
为了发布正确的消息,您还可以添加以下2行;
Request.SendChunked = true;
Request.TransferEncoding = "GB2312";
这也导致在该场合501
,你可以删除2线,并修改踵像这样。
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重定向是等于302。 下面一行是必须的:
Request.AllowAutoRedirect = false;
使用调试http代理看出差别正是在导线上的两个电话之间。试试Charles(http://www.charlesproxy.com/)或Fiddler(http://www.fiddler2.com/fiddler2/)。 – 2010-03-02 04:27:36