I have already tried various options, the code itself:

var parameters = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("login","***"), new KeyValuePair<string, string>("password","***"), new KeyValuePair<string, string>("get","***") }; var data = new FormUrlEncodedContent(parameters); HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://ekinobilet.ru/ekbs/upload.aspx"); request.Method = "POST"; byte[] dataArray = await data.ReadAsByteArrayAsync(); request.ContentLength = dataArray.Length; request.ContentType = "multipart/form-data"; var dataStream = await request.GetRequestStreamAsync(); dataStream.Write(dataArray, 0, dataArray.Length); dataStream.Close(); var resp = await request.GetResponseAsync(); dataStream = resp.GetResponseStream(); Stream receiveStream = resp.GetResponseStream(); StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); var responseText = readStream.ReadToEnd(); 

Actually the requirement itself: To download the contents of the “outgoing” folder from the ENI server, the film demonstrator sends a request to the Internet address: https://ekinobilet.ru/ekbs/upload.aspx via the HTTPS protocol, method: POST MIME type: multipart / form-data in accordance with RFC1867 ( http://www.ietf.org/rfc/rfc1867.txt ). The request must contain three parameters: 1) login (string, USERNAME); 2) password (string, PASSWORD); 3) XMLfile (file, XML document).

Since there is already a question "With #: passing parameters with a POST request", there is no answer to the solution of a more complicated option. I decided to change the question to "C #: passing parameters and POST data with a request in the format multipart / form-data".

  • The 500th error in ASP-NET is the worst, which means that an exception occurred in ASP-NET. Look for exactly which parameter does not like or lack ASP. If your host - run on the test in debug mode. Or put in the web.config <custom Errors mode="on"> , if someone else's - just carefully check the parameters. ASP can encrypt parameters, do session validation (you need to use cookies, and process all js libraries, not valid session = exception). - nick_n_a
  • Check with the sniffer the transmitted data from the browser to the site, and from your program to the site. By inconsistencies find an error. - nick_n_a
  • Does FormUrlEncodedContent really mean multipart / form-data? In my opinion not. We need to add something else. - nick_n_a
  • Earned, changed request.ContentType = "multipart / form-data" on application / x-www-form-urlencoded. And it all worked ... - Macro
  • Now I started returning at least some data ... :) - Macro

1 answer 1

I forgot to publish the solution to this problem.

First, create helper Upload class

 public class Upload { private static readonly Encoding encoding = Encoding.UTF8; public static HttpWebResponse MultipartFormDataPost(string postUrl, Dictionary<string, object> postParameters) { string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid()); string contentType = "multipart/form-data; boundary=" + formDataBoundary; byte[] formData = GetMultipartFormData(postParameters, formDataBoundary); return PostForm(postUrl, contentType, formData); } private static HttpWebResponse PostForm(string postUrl, string contentType, byte[] formData) { HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest; if (request == null) { throw new NullReferenceException("request is not a http request"); } request.Method = "POST"; request.ContentType = contentType; request.CookieContainer = new CookieContainer(); request.ContentLength = formData.Length; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(formData, 0, formData.Length); requestStream.Close(); } return request.GetResponse() as HttpWebResponse; } private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary) { Stream formDataStream = new System.IO.MemoryStream(); bool needsCLRF = false; foreach (var param in postParameters) { if (needsCLRF) formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n")); needsCLRF = true; if (param.Value is FileParameter) { FileParameter fileToUpload = (FileParameter)param.Value; string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", boundary, param.Key, fileToUpload.FileName ?? param.Key, fileToUpload.ContentType ?? "application/octet-stream"); formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header)); formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length); } else { string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", boundary, param.Key, param.Value); formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData)); } } string footer = "\r\n--" + boundary + "--\r\n"; formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer)); formDataStream.Position = 0; byte[] formData = new byte[formDataStream.Length]; formDataStream.Read(formData, 0, formData.Length); formDataStream.Close(); return formData; } public class FileParameter { public byte[] File { get; set; } public string FileName { get; set; } public string ContentType { get; set; } public FileParameter(byte[] file) : this(file, null) { } public FileParameter(byte[] file, string filename) : this(file, filename, null) { } public FileParameter(byte[] file, string filename, string contenttype) { File = file; FileName = filename; ContentType = contenttype; } } } 

Further, already in the button itself a piece of code:

 Dictionary<string, object> postParameters = new Dictionary<string, object>(); postParameters.Add("login", cinema.org_login); postParameters.Add("password", cinema.org_password); postParameters.Add("XMLfile", new Upload.FileParameter(data, fileName, "application/xml")); string postURL = "https://...."; HttpWebResponse webResponse = Upload.MultipartFormDataPost(postURL, postParameters); StreamReader responseReader = new StreamReader(webResponse.GetResponseStream()); string fullResponse = responseReader.ReadToEnd(); webResponse.Close(); Response.Write(fullResponse);