我正在尝试将我的Android应用程序中的图片上传到我的IIS服务器上的web api项目。首先,在Android端,我做了以下自定义排球请求:
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;
}
以下代码说明了我如何构建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);
}
MIMEType的构建如下:
long boundary = System.currentTimeMillis();
String mimeType = "multipart/form-data;boundary=" + boundary;
在服务器端,在地址 Profil / UpdatePicture 下的控制器上 我有以下捕获多数据表单请求的方法:
[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;
}
如您所见,我使用自定义 MultipartFormStreamProvider 来制作自定义文件名模式。
当我尝试在Web api UI上从HTML表单上传图片时,上传成功。但是当我使用上面的排球请求从我的Android应用程序上传时,即使我得到200 Http代码作为回报,图片也没有上传... IIS服务器完全控制图片必须的目标文件夹上传。 我正在处理这个问题已经两天了...... 有人看到问题在哪里吗?