You need to send a file from the console application in C # to the web server and then receive the data. Watching examples, but not working. How to organize sending a halyard?

I do so

string uri = "http://mysite/api/postfile"; string localPath = @"c:\path_to_file.doc"; var parameters = new System.Collections.Specialized.NameValueCollection() { { "parametr1", "parametr1_Value" } }; using (var client = new WebClient()) { client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; client.QueryString = parameters; var responseBytes = client.UploadFile(uri, localPath); var response = Encoding.UTF8.GetString(responseBytes); Console.WriteLine("\n Ответ \n {0}", response); } 

On server accepts controller

 public class PostFileController : Controller { [HttpPost] public ActionResult Index(HttpPostedFileBase upload) { if (upload != null) { // получаем имя файла string fileName = System.IO.Path.GetFileName(upload.FileName); // сохраняем файл в папку Files в проекте upload.SaveAs(Server.MapPath("~/Files/" + fileName)); return Content("1"); } else { return Content("0"); } } } 
  • What server, what examples, what is not working? Give your code. - Zufir
  • @Zufir Asp Net MVC Server, common C # application. Sending a file either by form or bytes is not important. But something does not send. I tried to send via WebClient on the application - Rakzin Roman
  • Is that the HTTP Post, if the server supports. - VladD
  • one
    Wait, that is, in the [HttpPost] -method data is coming? What do you mean by “second step”? - VladD
  • one
    @VladD, the question should sound like this: there is a certain server on which you can upload a file from a browser through a form. How to write a file in C # so that the server handles it correctly. - Qwertiy

4 answers 4

Try this:

 using (var client = new HttpClient()) using (var formData = new MultipartFormDataContent()) using (var fileStream = File.OpenRead(localPath)) { HttpContent fileStreamContent = new StreamContent(fileStream); var filename = Path.GetFileName(localPath); // эмулируем <input type="file" name="upload"/> formData.Add(fileStreamContent, "upload"); // эмулируем (action="{url}" method="post") var response = await client.PostAsync(url, formData); // и т. д. } 

Borrowed here .


If you really, really don't want asynchronous code, you can make a blocking call (but I would not recommend it):

  var response = client.PostAsync(url, formData).Result; 
  • I emulated the insertion of a file into a form, and now it does not accept. ActionResult Index (HttpPostedFileBase upload) upload is empty in debug mode. How can I receive a file? - Rakzin Roman
  • I accept it as written here metanit.com/sharp/articles/26.php - Rakzin Roman
  • ABOUT! I did not know that there is such a class :) - Qwertiy
  • one
    @RakzinRoman, check the name . And in general, look at the steps from my answer. And also Expect100Continue off Expect100Continue . - Qwertiy
  • @VladD, await not forgotten? UPDATE: Ah, no, there is a Result . Well, do not do the same so ?! - Qwertiy

The file is transmitted in multipart/form-data encoding. Accordingly, it is necessary:

  1. Generate a splitter (for example, Asrf456BGe4h )

  2. Send header

     Content-Type: multipart/form-data; boundary=Asrf456BGe4h 
  3. send request body :

     (отсутствующая преамбула) --Asrf456BGe4h Content-Disposition: form-data; name="AttachedFile1"; filename="horror-photo-1.jpg" Content-Type: image/jpeg (пустая строка) (двоичное содержимое первой фотографии) --Asrf456BGe4h-- (отсутствующий эпилог - пустая строка) 

    Pay attention to the two hyphens at the end.

And then just about a thing like a puzzle for a few hours

  1. Install Fiddler
  2. You send the file through the browser, from where everything works.
  3. You look in fiddler what exactly went.
  4. You send with your code. You look in fiddler what went.
  5. You finish your code until the one you send in step 4 matches what was in 3.
  • Can it be easier? I need to transfer one file at a time. Whether it would work. Ato just seems to break my head for a few hours - Rakzin Roman
  • @RakzinRoman, can not be easier. Either rework the server so that it takes Stream (it was possible in WCF, it’s not up to date about webapi) and went as it is written in the next answer. - Qwertiy
  • @RakzinRoman, added the answer. - Qwertiy

It seems so:
Write file to stream:

 var file = File.ReadAllBytes(filename); var req = WebRequest.CreateHttp(url); //url - адрес сервера req.Method = WebRequestMethods.Http.Post; //Отправляете на сервер(думаю знаете как) 

an action that takes a stream of bytes must have a argument byte []
How to write the stream of bytes to the file described here:
https://stackoverflow.com/questions/6397235/write-bytes-to-file

  • one
    The question was how to transfer the file to a regular server. This is not the answer at all. - Qwertiy

At one time I wrote an article .Net in 1C. Asynchronous HTTP requests, Post sending several multipart / form-data files, compressing traffic using gzip, deflate, convenient parsing of sites, etc.

True there is an example on 1C but it is not particularly important.

  public async Task SendPostFile(string urlserviceapiSent) { using (var client = new System.Net.Http.HttpClient()) using (var content = new System.Net.Http.MultipartFormDataContent()) { client.BaseAddress = new System.Uri(urlserviceapiSent); var values = new System.Collections.Generic.Dictionary<String, String>() { { "Name", "name"}, { "id", "id"} }; // content.Add(new FormUrlEncodedContent(values)); foreach (var keyValuePair in values) { content.Add(new System.Net.Http.StringContent(keyValuePair.Value), keyValuePair.Key); } string fileName = @"C:/ТестXML"; var fileContent = new System.Net.Http.StreamContent(System.IO.File.OpenRead(fileName)); fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = System.IO.Path.GetFileName(fileName) }; content.Add(fileContent); // Вариант отправки двоичных данных из файла но более краткий var fileContent2 = new System.Net.Http.StreamContent(System.IO.File.OpenRead(fileName)); content.Add(fileContent2, "attachment", "TestXml"); var stringContent = new System.Net.Http.ByteArrayContent(Encoding.UTF8.GetBytes("Тестовая строка")); stringContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = "Строка" }; content.Add(stringContent); var requestUri = "api/values/SendFiles"; var result = await client.PostAsync(requestUri, content); var str = await result.Content.ReadAsStringAsync(); textBox.AppendText(str + Environment.NewLine); } } 

Gives out such

// This is what the sent request looks like // POST http: // localhost: 40320 / api / values ​​/ SendFiles HTTP / 1.1 // Content-Type: multipart / form-data; boundary = "9f2d525a-7383-46ab-8fc7-419d73486c02" // Host: localhost: 40320 // Content-Length: 811 // Expect: 100-continue // Connection: Keep-Alive

// - 9f2d525a-7383-46ab-8fc7-419d73486c02 // Content-Type: text / plain; charset = utf-8 // Content-Disposition: form-data; name = Name

// name // - 9f2d525a-7383-46ab-8fc7-419d73486c02 // Content-Type: text / plain; charset = utf-8 // Content-Disposition: form-data; name = id

// id // - 9f2d525a-7383-46ab-8fc7-419d73486c02 // Content-Disposition: form-data; filename = "=? utf-8? B? 0J / RgNC + 0YHRgtC + 0KHRgtGA0L7QutCw? ="; name = attachment // Content-Type: text / plain

// Test line // - 9f2d525a-7383-46ab-8fc7-419d73486c02 // Content-Disposition: form-data; filename = "=? utf-8? B? 0KLQtdGB0YJYTUw =? =" // Content-Type: application / octet-stream

// 12345 // - 9f2d525a-7383-46ab-8fc7-419d73486c02 // Content-Disposition: form-data; name = attachment; filename = TestXml; filename * = utf-8''TestXml

// 12345 // - 9f2d525a-7383-46ab-8fc7-419d73486c02--

There is also a link to the service http://pastebin.com/1kyhAdai

 [NonAction] string fileName(MultipartFileData fileData) { string fileName = fileData.Headers.ContentDisposition.FileName; if (string.IsNullOrEmpty(fileName)) { return ""; } if (fileName.StartsWith("\"") && fileName.EndsWith("\"")) { fileName = fileName.Trim('"'); } if (fileName.Contains(@"/") || fileName.Contains(@"\")) { fileName = Path.GetFileName(fileName); } return fileName; } [HttpPost] public async Task<HttpResponseMessage> SendFiles() { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root); try { StringBuilder sb = new StringBuilder(); // Holds the response body // Read the form data and return an async task. await Request.Content.ReadAsMultipartAsync(provider); // This illustrates how to get the form data. foreach (var key in provider.FormData.AllKeys) { foreach (var val in provider.FormData.GetValues(key)) { sb.Append(string.Format("{0}: {1}\n", key, val)); } } // This illustrates how to get the file names for uploaded files. foreach (var file in provider.FileData) { var fileInfo = new FileInfo(file.LocalFileName); sb.Append(string.Format("Uploaded file: {0} {1} ({2} bytes)\n", fileName(file), fileInfo.Name, fileInfo.Length)); } return new HttpResponseMessage() { Content = new StringContent(sb.ToString()) }; } catch (System.Exception e) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e); } }