尝试在请求对象中使用IFormFile发送api请求时出现400错误的请求

时间:2019-01-02 19:37:48

标签: asp.net-core asp.net-core-mvc asp.net-core-webapi asp.net-core-2.1

我很难弄清楚如何发送请求的IFormFile对象的一部分。这是一个API调用,用于上传图片。我找到了一些资源,并尝试了每个建议,但是当我尝试使用API​​时,总是收到400 Bad Request响应。 API和客户端都是ASP.NET Core 2.1

调用API

public async Task<ApiResponse<ImageDto>> AddImageToWebsite(AddImageToWebsiteRequest request)
{
      try
      {
        HttpClient client = new HttpClient();
        var url = $"{_apiInfo.Url}/portal/AddImageToWebsite";
        byte[] data;
        using (var br = new BinaryReader(request.Image.OpenReadStream()))
        {
          data = br.ReadBytes((int) request.Image.OpenReadStream().Length);
        }

        var bytes = new ByteArrayContent(data);
        MultipartFormDataContent multiContent = new MultipartFormDataContent();    

        multiContent.Add(bytes, "file", request.Image.FileName);
        multiContent.Add(new StringContent(request.WebsiteId.ToString()), "WebsiteId");
        multiContent.Add(new StringContent(request.AltText), "AltText");

        // BREAKS AFTER THIS POST CALL
        var apiResponse = await client.PostAsync(url, multiContent);

        // DESERIALIZE RESPONSE TO RESPONSE OBJECT HERE

      }
      catch (Exception ex)
      {
        Log.Error(ex, "Error calling api");
        return ApiResponse.InternalError<ImageDto>(ex.Message);
      }
}

AddImageToWebsiteRequest

public class AddImageToWebsiteRequest
{
    public int WebsiteId { get; set; }
    public IFormFile Image { get; set; }
    public string AltText { get; set; }
}

API呼叫

[HttpPost]
[Route("AddImageToWebsite")]
public async Task<JsonResult> AddImageToWebsite(AddImageToWebsiteRequest request)
{
  return await this.HandleRequest(async () =>
  {
    var website = _dataAccess.GetWebsite(request.WebsiteId);

    if (website == default(Website))
    {
      return ApiResponse.NotFound<ImageDto>("Website not found");
    }

    // UPLOAD IMAGE CODE HERE
  }
}

它甚至没有命中API调用。我还尝试按以下方式发布它,只要序列化对象中没有图像,它就可以工作。

另一种尝试

var stringContent = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
var apiResponse = await client.PostAsync(url, stringContent);

// DESERIALIZE RESPONSE TO RESPONSE OBJECT HERE

我在网上尝试了很多不同的建议,但似乎都没有用。

2 个答案:

答案 0 :(得分:3)

IFormFile仅适用于multipart/form-data编码的POST请求,即传统形式的帖子。如果要发送JSON,则“上载”必须是Base64字符串,并且需要绑定到byte[]

public class AddImageToWebsiteRequest
{
    public int WebsiteId { get; set; }
    public byte[] Image { get; set; }
    public string AltText { get; set; }
}

JsonConvert.SerializeObject将自动将byte[]转换为Base64字符串。

答案 1 :(得分:0)

您如何从视图发送此信息?如果您使用的是表单,则可以为其指定multipart / form-data类型,提供文件的输入类型,然后将其绑定到参数中的IFormFile。

查看:

<form id="fileupload" action="yourpath/AddImageToWebsite/" method="POST" enctype="multipart/form-data">
  <button type="submit" class="btn btn-primary start">
  </button>
  <input type="file" name="YourFile"/>
  <!--Whatever other things you need to input, use hidden fields-->
</form> 

控制器:

[HttpPost]
[Route("AddImageToWebsite")]
public async Task<JsonResult> AddImageToWebsite(IFormFile YourFile)
{
  //Do what you need....
}