I'm trying to upload a picture from my android app to a web api project on my IIS Server. First, on the Android Side, I made the following custom volley request:
public class PictureRequest extends Request<NetworkResponse> {
private String mMimeType;
private byte[] mMultipartBody;
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public PictureRequest(String url, String mimeType, byte[] multipartBody, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(Method.POST, (ApplicationController.getInstance().getWS_BASE_URI() + url), errorListener);
this.mMimeType = mimeType;
this.mMultipartBody = multipartBody;
this.mListener = listener;
this.mErrorListener = errorListener;
}
@Override
protected void deliverResponse(NetworkResponse response)
{
mListener.onResponse(response);
}
@Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
try {
return Response.success(response, HttpHeaderParser.parseCacheHeaders(response));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
@Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
String auth = "Basic " + Base64.encodeToString((ApplicationController.getInstance().getWS_KEY()+":").getBytes(),
Base64.NO_WRAP);
headers.put("Authorization", auth);
return headers;
}
@Override
public String getBodyContentType() {
return mMimeType;
}
@Override
public byte[] getBody() throws AuthFailureError {
return mMultipartBody;
}
The following codewhows how I build the multipart:
private void buildPart(DataOutputStream dataOutputStream, byte[] fileData, String fileName) throws IOException
{
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\"; filename=\""
+ fileName + "\"" + lineEnd);
dataOutputStream.writeBytes("Content-Type: image/png" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(fileData);
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024 * 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
// read file and write it into form...
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
}
The MIMEType is buils as follows:
long boundary = System.currentTimeMillis();
String mimeType = "multipart/form-data;boundary=" + boundary;
On the server side, on the controller under the adress Profil/UpdatePicture I have the following method that catch the multidata form request:
[HttpPost]
[Route("api/Profil/UpdatePicture")]
public async Task<HttpResponseMessage> UpdatePicture()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/Data/IN/ProfilPictures");
var provider = new CustomMultipartFormDataStreamProvider(root);
var task = await Request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
}
return Request.CreateResponse(HttpStatusCode.OK);
});
return task;
}
As you can see, i've used a custom MultipartFormStreamProvider in order to make a custom file name pattern.
When I'm trying to upload a picture from an HTML form on the web api UI, the upload succeded. But when I'm uploading from my Android App using the above volley request, even if I get a 200 Http code in return, the picture is not uploaded... The IIS server has total control on the targeted folders where the picture have to be uploaded. It's been two days that I'm dealing with that issue... Does somebody sees where is the problem ?