简体   繁体   中英

How to save as Image From Stream which is send in retrofit2 to wcf web service

I am sending a image file to wcf web service using retrofit, on saving side of wcf web service i am unable to save the stream file.

In android i creating like

//ApiInterface.class
@Multipart
@POST("RestService/json/PostUploadFile/")
Call<UploadFileResponse> uploadFile(@Part MultipartBody.Part file); 

service call be like

File file = new File(assets.get(0).getPath());
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);

// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part part = MultipartBody.Part.createFormData("imageData", file.getName(), requestFile);

//api call method
callUploadFile(part, this);

private void callUploadFile(MultipartBody.Part part,
                               MainInteractor.OnFinishedListener listenerP) {
            final MainInteractor.OnFinishedListener listener = listenerP;

            HashMap<String, String> headerMap = new HashMap<>();
            headerMap.put("SessionID", "");
            headerMap.put("UserName", "");
            OkHttpClient httpClient = ConnectToService.newInstance().addHeaders(getContext(), headerMap);

            ApiInterface apiService =
                    ConnectToService.newInstance()
                            .getClient(httpClient).create(ApiInterface.class);

            Call<UploadFileResponse> call = apiService.uploadFile(part);
            call.enqueue(new Callback<UploadFileResponse>() {
                @Override
                public void onResponse(Call<UploadFileResponse> call, Response<UploadFileResponse> response) {
                    onFinished(response.body().getResult());
                }

                @Override
                public void onFailure(Call<UploadFileResponse> call, Throwable t) {
                    if (t.getLocalizedMessage() != null) {
                        onFinishedFailure(t.getLocalizedMessage());
                    }
                }
            });
        }

In wcf webservice i am getting data in message but when i save i get argument exception error. 获取消息中的数据 保存时出错

EDITED: Below code works

Bitmap bm = BitmapFactory.decodeFile(assets.get(finalX).getPath());
                        Bitmap bitmap = Bitmap.createScaledBitmap(bm, 480, 480, true);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos); //bm is the bitmap object
                        byte[] byteArray = baos.toByteArray();
                        RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray);
                        callUploadFile(body, "File_" + finalX, MainFragment.this);

calling service method

private void callUploadFile(RequestBody body, String fileName,
                           MainInteractor.OnFinishedListener listenerP) {
        final MainInteractor.OnFinishedListener listener = listenerP;

        HashMap<String, String> headerMap = new HashMap<>();
        headerMap.put("SessionID", "");
        headerMap.put("UserName", "");
        headerMap.put("FileName", fileName);
        OkHttpClient httpClient = ConnectToService.newInstance().addHeaders(getContext(), headerMap);

        ApiInterface apiService =
                ConnectToService.newInstance()
                        .getClient(httpClient).create(ApiInterface.class);

        Call<UploadFileResponse> call = apiService.uploadFile(body);
        call.enqueue(new Callback<UploadFileResponse>() {
            @Override
            public void onResponse(Call<UploadFileResponse> call, Response<UploadFileResponse> response) {
                if (response != null && response.body() != null) {
                    onFinished(response.body().getResult());
                } else {
                    if (response.message() != null) {
                        onFinishedFailure(response.message());
                    }
                }
            }

            @Override
            public void onFailure(Call<UploadFileResponse> call, Throwable t) {
                if (t.getLocalizedMessage() != null) {
                    onFinishedFailure(t.getLocalizedMessage());
                }
            }
        });
    }

In wcf service

public string uploadFile(Stream imageData)
        {
            string fileName = WebOperationContext.Current.IncomingRequest.Headers.Get("fileName");
            string fileFullPath = "D:\\Share\\srinidhi\\Temp_" + fileName + ".Jpeg";

            Image img = System.Drawing.Image.FromStream(imageData);
            img.Save(fileFullPath, ImageFormat.Jpeg);

            return "success";
        }

In api call

@POST("RestService/json/PostUploadFile/")
    Call<UploadFileResponse> uploadFile(@Body RequestBody bytes);

It seems that your stream is submitted by the form-data, which means that the stream contains some unnecessary data, such as the other data in the submitted form-data. One thing must be noted that WCF doesn't support the form-data by default, we generally convert the data to the complete file data by using the third-party library, MultipartParser .
Here is the download page.
http://antscode.blogspot.com/2009/11/parsing-multipart-form-data-in-wcf.html
Under this circumstance, please use the below code segments to save the image.

public async Task UploadStream(Stream stream)
        {
            //the third-party library.
            MultipartParser parser = new MultipartParser(stream);

            if (parser.Success)
            {
                //absolute filename, extension included.
                var filename = parser.Filename;
                var filetype = parser.ContentType;
                var ext = Path.GetExtension(filename);
                using (var file = File.Create(Path.Combine(HostingEnvironment.MapPath("~/Uploads"), Guid.NewGuid().ToString() +ext)))
                {
                    await file.WriteAsync(parser.FileContents, 0, parser.FileContents.Length);
                }
            }
}

If the stream is the complete binary file, please consider the below code (we use the HTTP header to save the file extension since WCF doesn't allow to contain another parameter in the method signature).

public async Task UploadStream(Stream stream)
        {
            var context = WebOperationContext.Current;
            string filename = context.IncomingRequest.Headers["filename"].ToString();
            string ext = Path.GetExtension(filename);
            using (stream)
            {
                //save the image under the Uploads folder on the server-side(root directory).
                using (var file = File.Create(Path.Combine(HostingEnvironment.MapPath("~/Uploads"), Guid.NewGuid().ToString() + ext)))
                {
                    await stream.CopyToAsync(file);
                }
            }
        }

Feel free to let me know if the problem still exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM