1

I have a problem with the application sending the file to the web service. This is my endpoint/controller.

[HttpPost] public async Task<IActionResult> Post(List<IFormFile> files) { long size = files.Sum(f => f.Length); foreach (var formFile in files) { if (formFile.Length > 0) { var filePath = "C:\\Files\\TEST.pdf"; using (var stream = System.IO.File.Create(filePath)) { await formFile.CopyToAsync(stream); } } } 

This controller works fine in Postman.

and this is my application that makes the request:

 byte[] bytes = System.IO.File.ReadAllBytes("C:\\Files\\files.pdf"); Stream fileStream = File.OpenRead("C:\\Files\\files.pdf"); HttpContent bytesContent = new ByteArrayContent(bytes); using (var client = new HttpClient()) using (var formData = new MultipartFormDataContent()) { formData.Add(bytesContent,"file", "files.pdf"); try { var response = await client.PostAsync(url, formData); }catch(Exception ex) { Console.WriteLine(ex); } 

It doesn't work. I'm not receiving the file in controller. I also tried this:

 string fileToUpload = "C:\\Files\\files.pdf"; using (var client = new WebClient()) { byte[] result = client.UploadFile(url, fileToUpload); string responseAsString = Encoding.Default.GetString(result); } 

but the result is the same. Would you be able to help?

4
  • Do you have the logs available for us? Commented Sep 14, 2020 at 10:53
  • When calling the request "var response = await client.PostAsync (url, formData)" the program terminates, or calls the request which I receive in the controller but the ,,List<IFormFile> files" is null". It does not throw any exception. Looks like he's not sending the file. I don't know how to find out otherwise Commented Sep 14, 2020 at 11:01
  • When you are using HttpClient I bet you should also add some headers to request that will tell server that you are sending file. Check this answer stackoverflow.com/questions/42212406/… Commented Sep 14, 2020 at 11:10
  • For version with httpclient, the request is sent and not received by the controller. I do not know why Commented Sep 14, 2020 at 11:48

1 Answer 1

1

Update 15/09/2020

This is the upload codes in ConsoleApplication. And it works with small file but not large file.

 public static async Task upload(string url) { //const string url = "https://localhost:44308/file/post"; const string filePath = "C:\\Files\\files.pdf"; try { using (var httpClient = new HttpClient{ Timeout = TimeSpan.FromSeconds(3600) }) { using (var form = new MultipartFormDataContent()) { using (var fs = System.IO.File.OpenRead(filePath)) { fs.Position = 0; using (var streamContent = new StreamContent(fs)) { form.Add(streamContent, "files", Path.GetFileName(filePath)); HttpResponseMessage response = httpClient.PostAsync(url, form).Result; fs.Close(); } } } } } catch (Exception e) { Console.WriteLine(e.Message); } } 




There are two steps to fix your problem.

1.Add ContentType to Headers

bytesContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); 

2. The file parameter name in formData should match action parameter name.

formData.Add(bytesContent,"file", "files.pdf"); //should be files public async Task<IActionResult> Post(List<IFormFile> files) 

Update

HttpClient.PostAsync() doesn't work when awaited in Console Application. Instead of blocking with .Result, use .GetAwaiter().GetResult().

HttpResponseMessage response = httpClient.PostAsync(url, form).Result; 


Here is the code to show how to upload file.

Codes of Controller

public class FileController : Controller { [HttpPost] public async Task<IActionResult> Post(List<IFormFile> files) { long size = files.Sum(f => f.Length); foreach (var formFile in files) { if (formFile.Length > 0) { var filePath = "C:\\Files\\TEST.pdf"; using (var stream = System.IO.File.Create(filePath)) { await formFile.CopyToAsync(stream); } } } return Ok(); } [HttpGet] public async Task<IActionResult> upload() { const string url = "https://localhost:44308/file/post"; const string filePath = @"C:\\Files\\files.pdf"; using (var httpClient = new HttpClient()) { using (var form = new MultipartFormDataContent()) { using (var fs = System.IO.File.OpenRead(filePath)) { using (var streamContent = new StreamContent(fs)) { using (var fileContent = new ByteArrayContent(await streamContent.ReadAsByteArrayAsync())) { fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); // "file" parameter name should be the same as the server side input parameter name form.Add(fileContent, "files", Path.GetFileName(filePath)); HttpResponseMessage response = await httpClient.PostAsync(url, form); } } } } } return Ok(); } } 

Test

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your answer!! I have one question. Because I am creating, a console application that uploads the file to the web service. On line ,,var fileContent = new ByteArrayContent(await streamContent.ReadAsByteArrayAsync()" the application ends and does not continue. The application does not throw exceptions. Why is this happening?
@Sebastian , HttpClient.PostAsync() doesn't work when awaited in Console Application. Try HttpResponseMessage response = httpClient.PostAsync(url, form).Result;, and it works on my ConsoleApp.
I want to accept the answer because it's great, but I'm having trouble with filestream. I have error ReadTimeout = 'file.ReadTimeout' threw an exception of type 'System.InvalidOperationException' WriteTimeout = 'file.WriteTimeout' threw an exception of type 'System.InvalidOperationException'. I don't know how to fix it in console application. It works great on the web service.
@Sebastian, I found that your issue is related with the size of file. I haven't deal with that and will keep on working it.
@Micheal Thank you! I deal with it. In postman I use C# RestSharp. Copy and paste, and everthing is all right

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.