我需要使用HttpWebClient一次上传一系列文件。
我正在关注此主题中的示例代码:
Upload files with HTTPWebrequest (multipart/form-data)
当有几个人报告该线程时,我也收到HTTP状态500错误。我已尝试过该主题中提供的2个解决方案,但两个都不适合我。似乎在请求中存在与间距相关的问题,但我无法弄明白。
问题:
我应该使用什么资源来验证HTTP请求的格式是否正确?
如果我复制并粘贴文件部分,应该可以手动编写请求,对吗?
如果你知道一些有效的示例代码,请告诉我。
以下是我正在使用的代码:
public static void UploadFilesToRemoteUrl(string url, string[] files,
string logpath, NameValueCollection nvc)
{
long length = 0;
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials =
System.Net.CredentialCache.DefaultCredentials;
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
//string header = string.Format(headerTemplate, "file" + i, files[i]);
string header = string.Format(headerTemplate, "uplTheFile", files[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(files[i], FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
WebResponse webResponse2 = httpWebRequest2.GetResponse();
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
MessageBox.Show(reader2.ReadToEnd());
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
}
更新
感谢ck鼓励我继续使用小提琴手。这就是我需要找到解决这个问题的方法。
现在让我回答这里的问题。
1。我应该使用什么资源来验证HTTP请求的格式是否正确? a)标准。有RFC1867 http://www.faqs.org/rfcs/rfc1867.html。很好读。它解释了多重上传应该发生的对象,以及如何处理其他表单数据。限制是它没有直截了当地说明如何根据每个头和值之间的CRLF数量来格式化请求。我怀疑这些信息可能在HTTP RFC 2616 http://www.w3.org/Protocols/rfc2616/rfc2616.html中,但在我阅读的时间里读取的时间要长一些。此外,它的不同实现之间可能存在一些解释空间。
b)实际示例。获得真实示例的获胜组合一起使用curl和fiddler。我能够通过curl发送正确的上传请求,但curl的--trace-ascii没有给我我需要的原始标题。我基于它做出的近似值一直在失败,而且小提琴手似乎没有抓住它的流量。
然后我找到了一个解释curl不使用系统代理的链接。因此,为了捕获小提琴手的流量,必须输入curl -x 127.0.0.1:8888 www.happysmurfs.com现在我得到了我需要的原始标题。现在,使用正确的原始标题,对代码进行故障排除很简单,因为我有另一个文本标题来与它进行比较。
2。如果我复制并粘贴文件部分,应该可以手动编写请求,对吗? 是的,它似乎有可能,但正如ck所提到的,从提琴手那里获得一个可靠的,经过验证的标题,然后从那里进行修改要容易得多。
第3。如果你知道一些有用的示例代码,请告诉我。 上面的代码应该可以工作,但要注意这一行:
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
第一个\ r \ n不应该在那里。此外,在标题或边界的末尾不应该有新的双线(\ r \ n)。