Upload image from React Native to ASP.NET Core Web Api

Viewed 213

I'm using react-image-picker to take pictures and get the URI but I'm having problems receiving images as an IFormFile in my API. When using the "Content-Type": "multipart/form-data" header my array is null. Without it the array is empty but the data is there as a key-value pair the value is of type object inside HttpContext.Request.Form.

I've tried using both axios and fetch. I've tried sending the object as a blob with the content-type specified as image/jpeg, I've tried stringifying the Asset object but my request doesn't show a content-type for the FormData no matter what.

I tried creating a quick Vue project and the request goes through to my API as a file there without any issues.

It seems like the difference comes down to whether the FormData has a content-type specified. on Vue, it looks like

------WebKitFormBoundaryQoBY2Xgnc8K2sTzQ
 Content-Disposition: form-data; name="photos"; filename="2560px-Random_Turtle.jpg"
 Content-Type: image/jpeg

while in react it looks like. It looks like it even ignores the filename that's set in the append.

------WebKitFormBoundaryQoBY2Xgnc8K2sTzQ
 Content-Disposition: form-data; name="photos"

Is there any way to force the content-type in the FormData? Using Blob like this doesn't change the request in any way

data.append("photos", new Blob([JSON.stringify(photo)], {type: "image/jpeg"}), "2560px-Random_Turtle")

React Native (Not working)

export const TestWithPhotosAPI = async (photos: Asset[]) => {
  let data = new FormData();
  if (containerAndPhotos.photos) {
    containerAndPhotos.photos.forEach((photo) => {
      data.append("photos", photo as Blob, "2560px-Random_Turtle");
    });
  }
  fetch("https://myapi/postpicture", {
    method: "POST",
    body: data,
  });
};

Vue project (Works)

<script setup lang="ts">
import { ref } from 'vue'

const form = ref(null)

const files = ref<FormData>(new FormData)

const filesChange = (event ) => {
  console.log(event.target.files);
  Array.from(event.target.files).map((file, index) => {
    console.log(file);
    files.value.append("photos", file as Blob, event.target.files[index].name)
  })
}

const upload = () => {
  fetch(
    'https://myapi/postpicture',
    {
      method: "POST",
      body: files.value
    }
  );
}
</script>

<template>
  <form ref="form" @submit.prevent="upload">
    <input type="file" name="file" multiple @change="(event) => filesChange(event)" />
    <input type="submit" />
  </form>
</template>

API (Works with Vue)

[HttpPost]
public ActionResult SetAsDone([FromForm] ICollection<IFormFile> photos)
{
    var httpRequest = HttpContext.Request.Form;

    return Ok();
}
0 Answers
Related