我现在有这个工作 - 我的测试是使用 ASP.NET 托管的网页......但基本技术应该可以在任何地方工作。
手动发布到 Web 服务器可能会有点棘手。我总是从 HttpWatch 之类的好工具开始 - 我在页面上发布一个真实的帖子,然后使用该工具查看它发布的内容,查看发送的标头,并查看发送的 cookie。
在这种情况下,标头中的内容类型设置为multipart/form-data,并定义了边界。然后查看流,您可以看到字节是如何发送到服务器的。
完成这些步骤后,您只需弄清楚如何从 c# 发送相同的字节。
此示例代码仅显示一个工作示例。显然,生产代码需要更进一步:
1) 它将首先连接以获得新的 __VIEWSTATE 和 __EVENTVALIDATION 参数,而不是像我在这里那样硬连线它们。
2) 它会查看表单参数(fname、lname)并确认它们的名称。
3) 它可能会寻找新的参数。
4) 每次都可能生成boundry。不确定这个,但浏览器是这样做的。
5) 文件名不会硬连线。
6) 可能有一种更有效的方法来创建最终字节数组。
代码如下:
private void SimulatePost_Click(object sender, EventArgs e)
{
WebClient client = new WebClient();
const string boundry = "---------------------------7dc2a722a12c8";
string contentType = string.Format("multipart/form-data; boundary={0}", boundry);
string postData = string.Format(@"--{0}
Content-Disposition: form-data; name=""__VIEWSTATE""
/wEPDwUKLTk2MDkyMzQyMw9kFgJmD2QWAgIDDxYCHgdlbmN0eXBlBRNtdWx0aXBhcnQvZm9ybS1kYXRhZGQLrqV5FQTzi8K9ogSJlS44c0L0Ou3+MaYfFPwjKPwjZQ==
--{0}
Content-Disposition: form-data; name=""__EVENTVALIDATION""
/wEWBAKXx6zsBALa1ffGCwK80PHQDQLurOv8AU7Jo8sYj9+E/zw7RsmFraAotTazyvQc7T2VseLqSwGO
--{0}
Content-Disposition: form-data; name=""ctl00$MainContent$fname""
jim
--{0}
Content-Disposition: form-data; name=""ctl00$MainContent$lname""
bob
--{0}
Content-Disposition: form-data; name=""ctl00$MainContent$picUpload""; filename=""C:\temp\small.JPG""
Content-Type: image/jpeg
", boundry);
string endData = string.Format(@"
--{0}
Content-Disposition: form-data; name=""ctl00$MainContent$post""
--{0}--
", boundry);
List<byte> postByteArray = Encoding.UTF8.GetBytes(postData).ToList();
byte[] file = File.ReadAllBytes(@"C:\temp\small.JPG");
postByteArray.AddRange(file);
postByteArray.AddRange(Encoding.UTF8.GetBytes(endData));
client.Headers.Add("Content-Type", contentType);
client.UploadData("http://localhost:63247/Default.aspx", "POST", postByteArray.ToArray());
}