C# 如何从 HttpClient post 一个带有文件作为表单数据的实体到 API?

C# How to post an entity with a file as form-data from HttpClient to API?

我有一个 ASP.NET 核心 API 接收这样的实体:

public class ChartDTO
{
    public string Name { get; set; }
    //public byte[] Image { get; set; }
    public IFormFile Image { get; set; }
}

API 控制器是:

     [HttpPost]
    [Route("[action]")]
    public ActionResult Register([FromForm] ChartDTO dto) // Using IFormFile
    {
        if (dto.Image.Length > 0)
        {
            var filePath = Path.Combine("wwwroot\Charts", dto.Name);
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                try
                {
                    dto.Image.CopyTo(fileStream);
                    return Ok(new { status = true, message = "Chart posted Successfully" });
                }
                catch (Exception)
                {
                    return BadRequest();
                }
            }
        }
        return BadRequest();
    }

它在 Postman 中运行良好(正文 = 表单数据,名称 =“DEV.png”,图像 = 文件),但我不知道如何在控制台应用程序中复制它。发现了很多类似的问题,但它们似乎都只专注于上传单个文件,而我需要一个实体。 Base64 字节数组是图像的一个选项,但我也无法让它工作。 非常感谢任何帮助。

TIA! 丹尼斯

试试这个,对我来说效果很好。您必须定义一个 MultipartFormDataContent

var requestContent = new MultipartFormDataContent(); 
var imageContent = new ByteArrayContent(ImageData);

requestContent.Add(imageContent, "image", "image.jpg");

await client.PostAsync(url, requestContent);

睡了一觉后,我意识到在这个项目中,我将无法使用 IFormFile,因为必须从 MetaTrader 4 加载和发送图像。因此,我必须使用一个字节[ ] 相反,这意味着整个解决方案最终是:

DTO:

public class ChartDTO
{
    public string Name { get; set; }
    public byte[] Image { get; set; }
}

控制器:

[HttpPost]
    [Route("[action]")]
    public ActionResult Register([FromBody] ChartDTO dto)
    {
        if (dto.Image.Length > 0)
        {
            string filePath = Path.Combine(env.WebRootPath + "\Charts\"+ dto.Name);
            try
            {
                using (FileStream binaryFileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite))
                {
                    binaryFileStream.Write(dto.Image, 0, dto.Image.Length);
                }
                return Ok();
            }
            catch (Exception)
            {
                return BadRequest();
            }
        }
        return BadRequest();
    }

应用程序:

 public static void UploadScreenshot(string accountName)
    {
        //string url = "https://localhost:44369/api/Charts/Register";
        string url = LocalItems.baseURL + LocalItems.chartsURL;
        string fileName = accountName + ".png";
        var filePath = Path.Combine(LocalItems.DataFolder + "\MQL4\Files\", fileName);

        if (File.Exists(filePath))
        {
            ChartDTO dto = new ChartDTO();
            dto.Name = fileName;
            dto.Image = File.ReadAllBytes(filePath);
            var json = JsonConvert.SerializeObject(dto);
            using (var client = new HttpClient())
            {
                // By calling .Result you are synchronously reading the result
                var response = client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json")).Result;
            }
        }
    }

抱歉浪费您的时间。

回复 丹尼斯