Wai Yan Hein Wai Yan Hein - 1 month ago 21
Android Question

Unable to upload multiple files or collection of files in mutipart/form-data request using retrofit in Android

I am developing an Android application. In my app, I need to upload multiple or collection of files to server in multipart/form-data request. I am using Retrofit 2 for it. I can upload single file to server. But when I upload list of file, file values are always null at the server side. Please see my code below.

This is my retrofit service interface

public interface ApiService {

@Multipart
@POST("Troll/CreateMemePost")
Call<ResponseBody> postMeme(@Part List<MultipartBody.Part> files, @Part("AuthToken") RequestBody authToken);
}


As you can see I am trying to upload list of file as first parameter.

This is how I upload in activity

final ArrayList<File> photoFiles = new ArrayList<File>();
ArrayList<MultipartBody.Part> files = new ArrayList<MultipartBody.Part>();
for(Bitmap bitmap: previewBitmaps)
{
File file = null;
try{
String fileName = String.valueOf(System.currentTimeMillis())+".jpeg";
file = new File(Environment.getExternalStorageDirectory(), fileName);
if(file.exists())
{
file.delete();
}
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
photoFiles.add(file);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),file);
MultipartBody.Part partFile = MultipartBody.Part.createFormData("multipart/form-data",file.getName(),requestFile);
files.add(partFile);
}
catch (Exception e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
}

if(files!=null && files.size()>0)
{
final Retrofit retrofit = app.getApiClient().getRetrofit();
ApiService service = app.getApiClient().getApiService();

RequestBody authToken = RequestBody.create(MediaType.parse("multipart/form-data"), app.getAuthToken());

Call<ResponseBody> call = service.postMeme(files,authToken);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(photoFiles!=null && photoFiles.size()>0)
{
for(File tempFile : photoFiles)
{
if(tempFile.exists())
{
tempFile.delete();
}
}
}
if(response!=null)
{
if(response.isSuccessful())
{
Toast.makeText(getBaseContext(),"File Uploaded successfully",Toast.LENGTH_SHORT).show();
}
else if(!response.isSuccessful() && response.errorBody()!=null)
{
Toast.makeText(getBaseContext(),"Server error message",Toast.LENGTH_SHORT).show();
/*try{

}
catch (IOException e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}*/
}
}
else{
Toast.makeText(getBaseContext(),"Response is null",Toast.LENGTH_SHORT).show();
}
}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if(photoFiles!=null && photoFiles.size()>0)
{
for(File tempFile : photoFiles)
{
if(tempFile.exists())
{
tempFile.delete();
}
}
}
Toast.makeText(getBaseContext(),"Unable to transfer data to server",Toast.LENGTH_SHORT).show();
}
});
}


But when I upload, I receive AuthToken field successfully at the server side. But the file values are always null. I am using ASP.NET MVC for backend. You can see the screenshot below. It is always null. U bind like this at server side.

public JsonResult CreateMemePost(IEnumerable<HttpPostedFileBase> files,CreateMemePostModel model)


files is always null and AuthToken field in model is present as sent from my app. When I upload single file like this

public JsonResult CreateMemePost(HttpPostedFileBase file,CreateMemePostModel model)


it is working and uploaded successfully. I am pretty sure that the problem is with my retrofit code. Please what is wrong with my code? How can I upload list of files to server in multipart/form-data request using retrofit in Android? Please help me. Please.


I tried this as well to upload files only


public interface ApiService {

@FormUrlEncoded
@POST("Troll/CreateMemePost")
Call<ResponseBody> postMeme(@Field("files") ArrayList<RequestBody> files);//, @Part("AuthToken") RequestBody authToken);
}


Files count is always 0 at the server side.


Then I tried another solution using MapPart


public interface ApiService {
@Multipart
@POST("Troll/CreateMemePost")
Call<ResponseBody> postMeme(@PartMap() Map<String,RequestBody> files, @Part("AuthToken") RequestBody authToken);
}


I create map like this in activity

HashMap<String,RequestBody> map = new HashMap<>();
// Other steps
MediaType MEDIA_TYPE=MediaType.parse("multipart/form-data");
bodyFile = RequestBody.create(MEDIA_TYPE,file);
map.put("files",bodyFile);


Files is always null at the server. Please give me a solution. Please help me. How can I solve it? Please.

Answer

Finally, I found the solution. I used RequestBody and MultipartBody.Builder. I uploaded the solution on Github.

Please have a look at this link - https://github.com/waiyanhein/how-to-upload-multiple-files-using-retrofit-in-android.