将图片从Android上传到WebApi项目

时间:2015-12-29 18:17:01

标签: android asp.net-web-api upload android-volley multipartform-data

我正在尝试将我的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服务器完全控制图片必须的目标文件夹上传。 我正在处理这个问题已经两天了...... 有人看到问题在哪里吗?

0 个答案:

没有答案