最近项目中需要使用httpwebrequest(C#)上传文件,服务器端需要附带文件的文件名称,所以在构造数据体时,需要加入参数信息,模拟网页的上传文件形式,以表单形式上传数据,具体代码:
// 边界符
var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
//开始符
var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
// 定义结束符
var endBoundary = Encoding.ASCII.GetBytes("\r\n" +"--" + boundary + "--\r\n");
// 数据内容说明字段(附带文件名称的参数信息)
const string filePartHeader =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
var fileHeader = string.Format(filePartHeader, "log", file);
var fileHeaderBytes = Encoding.UTF8.GetBytes(fileHeader);
// 写入起始符
var memStream = new MemoryStream();
memStream.Write(beginBoundary, 0, beginBoundary.Length);
// 写入实体数据头部信息,包含参数字段、实体数据头部信息
memStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);
//写入数据体
var buffer = new byte[4 * 1024];
int bytesRead;
var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
//写入最后的结束边界符
memStream.Write(endBoundary, 0, endBoundary.Length);
//获取流中字节信息,放入 tempBuffer 中
memStream.Position = 0;
var tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
// 设置请求头
var webRequest = (HttpWebRequest)WebRequest.Create(url);
//设置http协议头部信息
webRequest.Method = "POST";
webRequest.Timeout = 1000;
webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
webRequest.ContentLength = tempBuffer.Length;
//写入流数据
var requestStream = webRequest.GetRequestStream();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
//发送并获返回状态
var webRespon = await webRequest.GetResponse() as HttpWebResponse;
if (webRespon.StatusCode == HttpStatusCode.OK)
{
Stream s = webRespon.GetResponseStream();
StreamReader sr = new StreamReader(webRespon.GetResponseStream());
String sReturnString = (new StreamReader(webRespon.GetResponseStream())).ReadLine();
s.Close();
sr.Close();
return sReturnString;
}
以上就是构造实体数据并发送的过程,包含文件和参数信息的数据体。