Search code examples
c#asp.netweb-servicesuploadhttpwebrequest

Request with file to web API


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?


Solution

  • 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