向 Web API 请求文件

Posted

技术标签:

【中文标题】向 Web API 请求文件【英文标题】:Request with file to web API 【发布时间】:2020-09-14 10:34:19 【问题描述】:

应用程序将文件发送到 Web 服务时出现问题。这是我的端点/控制器。

[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);
                
            
        

这个控制器在 Postman 中运行良好。

这是我提出请求的应用程序:

             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);
                 

它不起作用。我没有在控制器中收到文件。我也试过这个:

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

但结果是一样的。你能帮忙吗?

【问题讨论】:

您有可供我们使用的日志吗? 当调用请求“var response = await client.PostAsync (url, formData)”时,程序终止,或调用我在控制器中收到的请求,但 ,,List 文件”一片空白”。它不会抛出任何异常。看起来他没有发送文件。我不知道如何找出其他的 当您使用 HttpClient 时,我敢打赌您还应该在请求中添加一些标头,以告知服务器您正在发送文件。检查这个答案***.com/questions/42212406/… 对于带有httpclient的版本,请求被发送,控制器不接收。我不知道为什么 【参考方案1】:

2020 年 9 月 15 日更新

这是ConsoleApplication中的上传代码。它适用于小文件,但不适用于大文件。

    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);
        

    

有两个步骤可以解决您的问题。

1.向Headers添加ContentType

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

2。 formData 中的文件参数名称应与操作参数名称匹配。

formData.Add(bytesContent,"file", "files.pdf"); //should be files


public async Task<IActionResult> Post(List<IFormFile> files)

更新

HttpClient.PostAsync() 在控制台应用程序中等待时不起作用。不要使用 .Result 阻塞,而是使用 .GetAwaiter().GetResult()。

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

这里是显示如何上传文件的代码。

控制者代码

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();

        
    

测试

【讨论】:

感谢您的回答!!我有一个问题。因为我正在创建一个将文件上传到 Web 服务的控制台应用程序。在线,,var fileContent = new ByteArrayContent(await streamContent.ReadAsByteArrayAsync()" 应用程序结束并没有继续。应用程序没有抛出异常。为什么会这样? @Sebastian , HttpClient.PostAsync() 在控制台应用程序中等待时不起作用。试试HttpResponseMessage response = httpClient.PostAsync(url, form).Result;,它可以在我的 ConsoleApp 上运行。 我想接受这个答案,因为它很棒,但我在使用文件流时遇到了问题。我有错误 ReadTimeout = 'file.ReadTimeout' 引发了“System.InvalidOperationException”类型的异常 WriteTimeout = 'file.WriteTimeout' 引发了“System.InvalidOperationException”类型的异常。我不知道如何在控制台应用程序中修复它。它在网络服务上效果很好。 @Sebastian,我发现您的问题与文件大小有关。我还没有处理这个问题,我会继续努力。 @Micheal 谢谢!我处理它。在邮递员中,我使用 C# RestSharp。复制粘贴,一切正常

以上是关于向 Web API 请求文件的主要内容,如果未能解决你的问题,请参考以下文章

向 ASP.NET Web API 发送请求时出现 CORS 错误

向 web api 发送 ajax 请求时出现 401 Unauthorized

如何从 ReactJS Web 应用程序向 Django API 发送 POST 请求?

无法使用javascript向ASP.NET web api Controller发送http POST请求

如何确保只有我的 javascript 客户端 Web 应用程序向 REST API 发出请求?

如何从 ASP.NET 核心 mvc 向 asp.net 核心中的 Web API 发出 PUT 请求?