Я хочу сделать POST для PHP-сайта из приложения C # WinForm в окне браузера (или экземпляра WebBrowser) с .net 2.0, и мне нужно правильно получить данные и заголовки-аргументы. Как:
webBrowser1.Navigate("http://mypublishservice.com/publish_picture.php","_SELF",X,Y);
Вопрос в том, какими должны быть X и Y? Я знаю, что нужно заполнить все заголовки и данные файла в массиве byte [] и добавить несколько дополнительных заголовков в виде строк. Я сделал примеры веб-формы ниже и исследовал их с помощью firebug. Так что я знаю, как должны выглядеть данные POST. Я даже создал HttpWebRequest, который был в порядке, но мне нужен WebBrowser (причины ниже), чтобы запустить пост-запрос. Так что я потерян. Я перепробовал много вариантов, например Загрузка файлов с помощью HTTPWebrequest (multipart / form-data) . Может быть, есть лучший способ, создав HttpWebrequest и передав его экземпляру WebBrowser или что-то в этом роде?
Вот веб-форма для вызова страницы publish_picture.php, которая отлично работает:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<form enctype="multipart/form-data" action="http://mypublishservice.com/publish_picture.php" method="POST">
Please choose a photo:
<input name="source" type="file"><br/><br/>
Say something about this photo:
<input name="message" type="text" value=""><br/><br/>
<input type="submit" value="Upload"/><br/>
</form>
</div>
</body>
</html>
Если вы спросите, почему я хочу сделать это НАСТОЯЩИМ, вот несколько мыслей, чтобы защитить мое глупое решение;)
Почему экземпляр WebBrowser, а не простой HttpWebrequest? Потому что целевой службе (например, Facebook) нужен (или, кажется, нужен) соответствующий браузер!
Почему не целевые сервисные API (например, Facebook API)? Выяснил, что Desktop-Web-связь не годится (слишком много 400-ошибок).
ОБНОВЛЕНИЕ 2:
выглядит лучше. Тем не менее я получаю сообщение об ошибке, но это может быть сама страница PHP. Это то, что ты имеешь в виду?
public static byte[] PrepareUploadFiles(string address, IEnumerable<UploadFile> files, NameValueCollection values, out string header)
{
using (var requestStream = new MemoryStream())
{
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); //, NumberFormatInfo.InvariantInfo);
header = "multipart/form-data; boundary=" + boundary;
var boundaryBuffer2 = Encoding.ASCII.GetBytes(header);
requestStream.Write(boundaryBuffer2, 0, boundaryBuffer2.Length);
boundary = "--" + boundary;
// Write the values
foreach (string name in values.Keys)
{
var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", name, Environment.NewLine));
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.UTF8.GetBytes(values[name] + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
}
// Write the files
foreach (var file in files)
{
var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"{2}", file.Name, file.Filename, Environment.NewLine));
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}{1}{1}", file.ContentType, Environment.NewLine));
requestStream.Write(buffer, 0, buffer.Length);
CopyStream(file.Stream, requestStream); // file.Stream.CopyTo(requestStream);
buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
}
var boundaryBuffer = Encoding.ASCII.GetBytes(boundary + "--");
requestStream.Write(boundaryBuffer, 0, boundaryBuffer.Length);
return requestStream.ToArray();
}
}
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
while (true)
{
int read = input.Read(buffer, 0, buffer.Length);
if (read <= 0)
return;
output.Write(buffer, 0, read);
}
}
public void Upload()
{
using (var stream1 = File.Open(Support.EXAMPLEIMAGE, FileMode.Open))
{
var files = new[]
{
new UploadFile
{
Name = "source", // 1
Filename = Support.EXAMPLEIMAGE,
ContentType = "image/jpeg", // 2
Stream = stream1
}
};
var values = new NameValueCollection
{
{ "message", "a text" } // 3
};
string contentType; // 4. do I need it
byte[] dataToPost = Support.PrepareUploadFiles(Support.URL, files, values, out contentType); // 5. out contentType = what should be the result vaule?
//PrepareUploadFiles(url, files, values, out contentType);
webBrowser1.Navigate(Support.URL, null, dataToPost, "Content-Type: " + contentType + Environment.NewLine);
}
}