【问题标题】:Request with file to web API向 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 时,我敢打赌您还应该在请求中添加一些标头,以告知服务器您正在发送文件。检查这个答案stackoverflow.com/questions/42212406/…
  • 对于带有httpclient的版本,请求被发送,控制器不接收。我不知道为什么

标签: c# asp.net web-services upload httpwebrequest


【解决方案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。复制粘贴,一切正常
猜你喜欢
  • 1970-01-01
  • 2019-01-26
  • 2016-05-12
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多