C#HttpWebRequest表单上传 [英] C# HttpWebRequest form upload
问题描述
im试图自动从我的C#程序上传文件.这是上传文件的方法.
im trying to automate a file upload from my C# program. This is the method to upload a file.
public static string UploadFileEx(string uploadfile, string url,
string fileFormName, string contenttype, NameValueCollection querystring,
CookieContainer cookies)
{
if ((fileFormName == null) ||
(fileFormName.Length == 0))
{
fileFormName = "file";
}
if ((contenttype == null) ||
(contenttype.Length == 0))
{
contenttype = "application/octet-stream";
}
string postdata;
postdata = "";
if (querystring != null)
{
foreach (string key in querystring.Keys)
{
postdata += key + "=" + querystring.Get(key) + "&";
}
}
Uri uri = new Uri(url + postdata);
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
var sp = webrequest.ServicePoint;
var prop = sp.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
prop.SetValue(sp, (byte)0, null);
webrequest.CookieContainer = cookies;
webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
webrequest.Method = "POST";
webrequest.KeepAlive = true;
webrequest.Referer = "http://www.iwi.hs-karlsruhe.de/scs/simulate/upload.jsp";
webrequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
webrequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1";
webrequest.Headers.Add("Accept-Language:de-de,de;q=0.8,en-us;q=0.5,en;q=0.3");
webrequest.Headers.Add("Accept-Encoding:gzip, deflate");
webrequest.ProtocolVersion = HttpVersion.Version11;
// Build up the post message header
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"");
sb.Append(fileFormName);
sb.Append("\"; filename=\"");
sb.Append(Path.GetFileName(uploadfile));
sb.Append("\"");
sb.Append("\r\n");
sb.Append("Content-Type: ");
sb.Append(contenttype);
sb.Append("\r\n");
sb.Append("\r\n");
string postHeader = sb.ToString();
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
// Build the trailing boundary string as a byte array
// ensuring the boundary appears on a line by itself
byte[] boundaryBytes =
Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
FileStream fileStream = new FileStream(uploadfile,
FileMode.Open, FileAccess.Read);
long length = postHeaderBytes.Length + fileStream.Length +
boundaryBytes.Length;
webrequest.ContentLength = length;
Stream requestStream = webrequest.GetRequestStream();
// Write out our post header
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
// Write out the file contents
byte[] buffer = new Byte[checked((uint)Math.Min(4096,
(int)fileStream.Length))];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
// Write out the trailing boundary
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
try
{
WebResponse responce = webrequest.GetResponse();
Stream s = responce.GetResponseStream();
StreamReader sr = new StreamReader(s);
return sr.ReadToEnd();
}
catch (Exception ex)
{
return ex.Message;
}
}
当我在示例图片上传页面上这样称呼它时,一切正常:
When i call it like this on a sample image upload page, everything works fine:
string outdata = UploadFileEx(uploadfile,
"http://www.minpic.de/upload_file.php", "uploadfile0", "image/jpg",
null, null);
但是,当我尝试将其上传到我的高中页面时,它不起作用.上传页面由登录表单保护.因此,我调用了上传页面以获取initail Cookie,然后发布登录凭据并获得正确的结果.这样我就可以看到以下上传表单:
But when i try to upload it to the page of my high school it's not working. The upload page is secured by a login form. So i call the upload page to get the initail Cookie, the i post the login credentials and get the right result. So i can see the following upload form:
<form action="../simulate" method=post enctype="multipart/form-data"><br />Choose your inputdata file (xml).<br /><input type=file size=50 maxlength=100000 name="Datei" accept="text/xml"><br><br><input type=submit value="Send"></form>
当我随后发布图像时(我知道期望的类型是xml,但页面在这种情况下回答了我想要的错误...),我的上传函数返回了错误代码500.这是Wireshark对浏览器的说明帖子:
When i then post the image (i know the expected type is xml but the page answers a error what i want in this case ...) my upload function return a error code 500. Here is what wireshark says for the browsers post:
POST/scs/模拟HTTP/1.1 主持人:一些主持人 连接:保持活动状态 内容长度:3874 快取控制:max-age = 0 来源:同一主机 用户代理:Mozilla/5.0(Windows NT 6.1)AppleWebKit/537.4(KHTML,例如Gecko)Chrome/22.0.1229.79 Safari/537.4 内容类型:多部分/表单数据; boundary = ---- WebKitFormBoundaryP3Ti6rxYcN1ov7JD 接受:text/html,application/xhtml + xml,application/xml; q = 0.9,/; q = 0.8 引荐来源:一些网址 接受编码:gzip,deflate,sdch 接受语言:de-DE,de; q = 0.8,en-US; q = 0.6,en; q = 0.4 接受字符集:ISO-8859-1,utf-8; q = 0.7,*; q = 0.3 Cookie:SCS_COOKIE = Default = DE $$ MarkePlaceLang = DE; JSESSIONID = B459541362241F66D9312AF157262D25
POST /scs/simulate HTTP/1.1 Host: some host Connection: keep-alive Content-Length: 3874 Cache-Control: max-age=0 Origin: same host User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryP3Ti6rxYcN1ov7JD Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Referer: some url Accept-Encoding: gzip,deflate,sdch Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: SCS_COOKIE=Default=DE$$MarkePlaceLang=DE; JSESSIONID=B459541362241F66D9312AF157262D25
这里是c#的帖子:
POST与上述相同 内容类型:多部分/表单数据;边界= ---------- 8cf828671b8365c 引荐来源:一些网址 接受:text/html,application/xhtml + xml,application/xml; q = 0.9,/; q = 0.8 用户代理:Mozilla/5.0(Windows NT 6.1; WOW64)AppleWebKit/535.1(KHTML,例如Gecko)Chrome/13.0.782.220 Safari/535.1 接受语言:de-de,de; q = 0.8,en-us; q = 0.5,en; q = 0.3 接受编码:gzip,放气 主机:与上述相同的主机 Cookie:JSESSIONID = FFE0B7530FFE6A3C8F15FD8A900865B0 内容长度:3847 期望:100-继续 连接:保持活动状态
POST same as above Content-Type: multipart/form-data; boundary=----------8cf828671b8365c Referer: some url Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1 Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Host: same host as above Cookie: JSESSIONID=FFE0B7530FFE6A3C8F15FD8A900865B0 Content-Length: 3847 Expect: 100-continue Connection: Keep-Alive
我可以看到的唯一区别是Expect:100-continue ...数据包大小是否有问题?
The only difference i can see is the Expect: 100-continue ... Is there a problem with the packet size or something ?
提前谢谢.
推荐答案
您必须使用分段上传.这显示在您的浏览器帖子中:
you have to upload using multipart. This is shown in your browser post:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryP3Ti6rxYcN1ov7JD
这是一个示例: 使用HTTPWebrequest(multipart/form-data)上传文件
这是有道理的,因为通常图像的大小可能会超出通常发布的限制(我忘记了2KB或4KB).
it makes sense because usually image size may be larger than the limit of usual post (2KB or 4KB, I forgot).
这篇关于C#HttpWebRequest表单上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!