В двух словах, после создания запроса, надо открыть RequestStream, записать в него все POST данные и отправить на сервер.
Вот выдернул из готового проекта отправку POST запроса:
// в data передаются параметры POST (ключ - значение)
// если надо загрузить файл - передаётся в file
internal static string Post(string url, Dictionary<string, string> data, FileUploadData file = null)
{
string ServerResponse = null;
HttpWebRequest wrq = (HttpWebRequest)HttpWebRequest.Create(url);
wrq.Method = WebRequestMethods.Http.Post;
wrq.UserAgent = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name +
System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
wrq.Timeout = 600000;
try
{
// Это на случай использования прокси, можно выкинуть
if (Config.UseProxy)
{
WebProxy proxy = new WebProxy(Config.ProxyAddress, Config.ProxyPort);
if (Config.ProxyLogin != string.Empty || Config.ProxyPass != string.Empty)
{
proxy.Credentials = new NetworkCredential(Config.ProxyLogin, Config.ProxyPass);
proxy.UseDefaultCredentials = false;
}
else
{
proxy.UseDefaultCredentials = true;
}
}
if (null == file) // проверяем, надо ли загружать файл на сервер
{
wrq.ContentType = "application/x-www-form-urlencoded";
Stream requestStream = wrq.GetRequestStream();
List<string> keydata = new List<string>();
foreach (string key in data.Keys)
{
keydata.Add($"{HttpUtility.UrlEncode(key)}={HttpUtility.UrlEncode(data[key])}");
}
WriteToStream(requestStream, string.Join("&", keydata));
requestStream.Flush();
}
else
{
// Формируем multipart/form-data (отправка данных с формы)
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
wrq.ContentType = "multipart/form-data; boundary =" + boundary;
Stream requestStream = wrq.GetRequestStream();
WriteMultipartForm(requestStream, boundary, data, file);
}
// Посылаем данные на сервер и ждём ответа
wrq.BeginGetResponse(a =>
{
try
{
WebResponse resp = wrq.EndGetResponse(a);
Stream respStr = resp.GetResponseStream();
using (StreamReader sr = new StreamReader(respStr))
{
ServerResponse = sr.ReadToEnd();
} // using sr
} // try
catch (Exception ex)
{
Logger.LogError("Transport.Post", Globalizer.ID_Transport_Request_executing_error, ex);
} // catch
}, null);
} // try
catch(Exception ex)
{
Logger.LogError("Transport.Post", Globalizer.ID_Transport_Could_not_connect_to_server, ex);
return null;
}
return ServerResponse;
} // Post
private static void WriteMultipartForm(Stream s, string boundary, Dictionary<string, string> data, FileUploadData file)
{
/// The first boundary
byte[] boundarybytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
/// the last boundary.
byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
/// the form data, properly formatted
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
/// the form-data file upload, properly formatted
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
/// Added to track if we need a CRLF or not.
bool bNeedsCRLF = false;
if (data != null)
{
foreach (string key in data.Keys)
{
/// if we need to drop a CRLF, do that.
if (bNeedsCRLF)
WriteToStream(s, "\r\n");
/// Write the boundary.
WriteToStream(s, boundarybytes);
/// Write the key.
WriteToStream(s, string.Format(formdataTemplate, key, data[key]));
bNeedsCRLF = true;
}
}
/// If we don't have keys, we don't need a crlf.
if (bNeedsCRLF)
WriteToStream(s, "\r\n");
WriteToStream(s, boundarybytes);
WriteToStream(s, string.Format(fileheaderTemplate, file.FieldName, file.Filename, file.ContentType));
/// Write the file data to the stream.
WriteToStream(s, file.FileData);
WriteToStream(s, trailer);
}
private static void WriteToStream(Stream s, string txt)
{
byte[] bytes = Encoding.UTF8.GetBytes(txt);
s.Write(bytes, 0, bytes.Length);
} // WriteToStream