Unable to upload multiple files or collection of files in mutipart/form-data request using retrofit in Android
<p>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.</p>

<p>This is my retrofit service interface</p>

<pre><code>public interface ApiService {

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

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

<p>This is how I upload in activity</p>

<pre><code>final ArrayList&lt;File&gt; photoFiles = new ArrayList&lt;File&gt;();
        ArrayList&lt;MultipartBody.Part&gt; files = new ArrayList&lt;MultipartBody.Part&gt;();
        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 &amp;&amp; files.size()&gt;0)
        {
            final Retrofit retrofit = app.getApiClient().getRetrofit();
            ApiService service = app.getApiClient().getApiService();

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

            Call&lt;ResponseBody&gt; call = service.postMeme(files,authToken);
            call.enqueue(new Callback&lt;ResponseBody&gt;() {
                @Override
                public void onResponse(Call&lt;ResponseBody&gt; call, Response&lt;ResponseBody&gt; response) {
                    if(photoFiles!=null &amp;&amp; photoFiles.size()&gt;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() &amp;&amp; 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&lt;ResponseBody&gt; call, Throwable t) {
                    if(photoFiles!=null &amp;&amp; photoFiles.size()&gt;0)
                    {
                        for(File tempFile : photoFiles)
                        {
                            if(tempFile.exists())
                            {
                                tempFile.delete();
                            }
                        }
                    }
                    Toast.makeText(getBaseContext(),"Unable to transfer data to server",Toast.LENGTH_SHORT).show();
                }
            });
        }
</code></pre>

<p>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.</p>

<pre><code>public JsonResult CreateMemePost(IEnumerable&lt;HttpPostedFileBase&gt; files,CreateMemePostModel model)
</code></pre>

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

<pre><code>public JsonResult CreateMemePost(HttpPostedFileBase file,CreateMemePostModel model)
</code></pre>

<p>It is working and uploaded successfully. I am pretty sure that the problem is with my retrofit code. What is wrong with my code? How can I upload list of files to server in multipart/form-data request using retrofit in Android? </p>

<p>I tried this as well to upload files only</p>

<pre><code>public interface ApiService {

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

<p>Files count is always 0 at the server side.</p>

<p>Then I tried another solution using MapPart</p>

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

<p>I create map like this in activity</p>

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

<p>Files is always null at the server.</p>