400 Bad Request при попытке отправить API-запрос с IFormFile в объекте запроса - PullRequest
0 голосов
/ 02 января 2019

Мне трудно понять, как отправить объект запроса IFormFile в часть запроса. Это вызов API для загрузки изображения. Я нашел несколько ресурсов и попробовал каждое предложение, но всегда получаю ответ 400 Bad Request, когда пытаюсь нажать API. И 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 CALL

[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 голосов
/ 03 января 2019

Как вы отправляете это из представления?Если вы используете форму, вы можете просто присвоить ей тип 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....
}
0 голосов
/ 02 января 2019

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[] s в строки Base64.

...