How to post form-data IFormFile with HttpClient?

后端 未结 4 1563
暖寄归人
暖寄归人 2021-01-04 07:22

I have backend endpoint Task Post(IFormFile csvFile) and I need to call this endpoint from HttpClient. Currently I am getting Unsuppor

相关标签:
4条回答
  • 2021-01-04 07:30

    Use this snippet:

    const string url = "https://localhost:5001/api/Upload";
    const string filePath = @"C:\Path\To\File.png";
    
    using (var httpClient = new HttpClient())
    {
        using (var form = new MultipartFormDataContent())
        {
            using (var fs = 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, "file", Path.GetFileName(filePath));
                        HttpResponseMessage response = await httpClient.PostAsync(url, form);
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-04 07:36

    Solved by using this code:

            const string fileName = "csvFile.csv";
            var filePath = Path.Combine("IntegrationTests", fileName);
            var bytes = File.ReadAllBytes(filePath);
            var form = new MultipartFormDataContent();
            var content = new StreamContent(new MemoryStream(bytes));
            form.Add(content, "csvFile");
            content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "csvFile",
                FileName = fileName
            };
            content.Headers.Remove("Content-Type");
            content.Headers.Add("Content-Type", "application/octet-stream; boundary=----WebKitFormBoundaryMRxYYlVt8KWT8TU3");
            form.Add(content);
    
            //Act
            var postResponse = await _sellerClient.PostAsync("items/upload", form);
    
    0 讨论(0)
  • 2021-01-04 07:42

    This worked for me as a generic

    public static Task<HttpResponseMessage> PostFormDataAsync<T>(this HttpClient httpClient, string url, string token, T data)
        {
            var content = new MultipartFormDataContent();
    
            foreach (var prop in data.GetType().GetProperties())
            {
                var value = prop.GetValue(data);
                if (value is FormFile)
                {
                    var file = value as FormFile;
                    content.Add(new StreamContent(file.OpenReadStream()), prop.Name, file.FileName);
                    content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = prop.Name, FileName = file.FileName };
                }
                else
                {
                    content.Add(new StringContent(JsonConvert.SerializeObject(value)), prop.Name);
                }
            }
    
            if (!string.IsNullOrWhiteSpace(token))
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            return httpClient.PostAsync(url, content);
        }
    
    0 讨论(0)
  • 2021-01-04 07:47

    You need to specify parameter name in MultipartFormDataContent collection matching action parameter name (csvFile) and a random file name

    var multipartContent = new MultipartFormDataContent();
    multipartContent.Add(byteArrayContent, "csvFile", "filename");
    var postResponse = await _client.PostAsync("offers", multipartContent);
    

    or equivalent

    var postResponse = await _client.PostAsync("offers", new MultipartFormDataContent {
        { byteArrayContent, "csvFile", "filename" }
    });
    
    0 讨论(0)
提交回复
热议问题