I am new to making Requestbody to send form data which consists of uploading an image from my phone media and some data which are in string format. I have used it in Postman and it's working but in my app I am facing problem where it gives 400 bad request when posting data to API. Here is my codes. Any help would do
This is my backend api code.
[HttpPost]
public ActionResult<FishReadDTO> CreateFish([FromForm] FishCreateDTO fishCreateDTO)
{
var fishmodel = _mapper.Map<Fish>(fishCreateDTO);
if(fishCreateDTO.ImageFile.Length > 0 || fishCreateDTO.ImageFile != null)
{
string apiServerAddress = _httpContextAccessor.HttpContext.Request.Scheme + "://"
+ _httpContextAccessor.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString()
+ ":" + _httpContextAccessor.HttpContext.Connection.LocalPort;
try
{
if(!Directory.Exists(_webHostEnvironment.WebRootPath + "\\images\\"))
{
Directory.CreateDirectory(_webHostEnvironment.WebRootPath + "\\images\\");
}
using (FileStream filestream = System.IO.File.Create(_webHostEnvironment.WebRootPath + "\\images\\" + fishCreateDTO.ImageFile.FileName))
{
fishCreateDTO.ImageFile.CopyTo(filestream);
filestream.Flush();
fishmodel.Image = apiServerAddress + "/images/" + fishCreateDTO.ImageFile.FileName;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error Occured {ex.Message}");
}
}
_repository.CreateFish(fishmodel);
var fishRead = _mapper.Map<FishReadDTO>(fishmodel);
return CreatedAtRoute(nameof(GetFishById), new{Id = fishRead.ID}, fishRead);
}
Here is my Fish Create DTO.
public class FishCreateDTO
{
[Required]
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(100)]
public string Description { get; set; }
[Required]
public float WeightKg { get; set; }
[Required]
public int Stock { get; set; }
[Required]
public float Price { get; set; }
[Required]
public int CategoryID { get; set; }
[Required]
public int UserID { get; set; }
public IFormFile ImageFile {get; set;}
}
For the front-end, I am using android Kotlin which also involves with Retrofit2.
Here is the api call
@Multipart
@POST("/efishing-api/fish")
suspend fun createFish(
@Part("name") name: String,
@Part("description") description : String,
@Part("weightKG") weightKG: String,
@Part("stock") stock : String,
@Part("price") price : String,
@Part("categoryID") categoryID: String,
@Part("userID") userID : String,
@Part imageFile : MultipartBody.Part
) : FishCreateResponse
Here is the repository.
suspend fun createFish(
name : String,
description : String,
weightKG : String,
stock : String,
price : String,
userId: String,
categoryId: String,
imageFile : MultipartBody.Part
) : FishCreateResponse {
return RetrofitBuilder.apiService.createFish(
name,
description,
weightKG,
stock,
price,
categoryId,
userId,
imageFile
)
}
Here is the viewmodel that I am using
fun createFish(
name : String,
description : String,
weightKG : String,
stock : String,
price : String,
userId: String,
categoryId: String,
imageFile : MultipartBody.Part
) {
CoroutineScope(IO).launch {
val fishCreate = fishRepository.createFish(
name,
description,
weightKG,
stock,
price,
categoryId,
userId,
imageFile
)
}
}
Here is where I am trying to upload my form data
val file = File(filePath)
val requestBody = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
fishViewModel.createFish(
Fishname.text.toString(),
Description.text.toString(),
FishPrice.text.toString(),
Weight.text.toString(),
Stock.text.toString(),
categoryID.toString(),
userId.toString(),
MultipartBody.Part.createFormData("imageFile", file.name, requestBody)
)
Here is the logcat
2021-07-20 01:49:31.117 24404-25371/com.example.efishingapp E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3
Process: com.example.efishingapp, PID: 24404
retrofit2.HttpException: HTTP 400 Bad Request
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:53)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:161)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
*Update (My Retrofit)
@Multipart
@POST("/efishing-api/fish")
suspend fun createFish(
@Part("name") name: String,
@Part("description") description : String,
@Part("weightKG") weightKG: String,
@Part("stock") stock : String,
@Part("price") price : String,
@Part("categoryID") categoryID: String,
@Part("userID") userID : String,
@Part imageFile : MultipartBody.Part
) : FishCreateResponse
Any solutions will do. Thanks