Retrofit 2 无法上传带有两个额外单独字符串参数的文件 [英] Retrofit 2 can't upload a file with two additional separate string parameters

查看:35
本文介绍了Retrofit 2 无法上传带有两个额外单独字符串参数的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读问题底部的编辑以获取可能的替代解决方案,直到找到解决方案.

这是一个使用 POSTMan 的带有两个参数的成功 post 文件.我正在尝试对改造做同样的事情,但收到 BadRequest.

邮递员设置:

Chrome 网络帖子详情:

现在这是我在 Android 中执行此操作但失败的方法:

改造服务接口:

@Multipart@POST("jobDocuments/上传")呼叫<响应体>upload(@Part("file") MultipartBody.Part 文件,@Part("folder") MultipartBody.Part 文件夹,@Part("name") MultipartBody.Part name);

这是我的@Background 方法,用于运行生成上述服务的网络请求

CustDataClient 服务 =ServiceGenerator.createService(CustDataClient.class);File file = new File(fileUri.getPath());//从文件创建 RequestBody 实例RequestBody requestFile =RequestBody.create(MediaType.parse("multipart/form-data"), file);MultipartBody.Part 文件数据 =MultipartBody.Part.createFormData("file", fileName, requestFile);MultipartBody.Part 文件夹 =MultipartBody.Part.createFormData("folder", "LeadDocuments");MultipartBody.Part 名称 =MultipartBody.Part.createFormData("name", fileName);//最后,执行请求呼叫<响应体>call = service.upload(fileData,folder,name);尝试 {响应<响应体>rr = call.execute();ResponseBody empJobDocsResult = rr.body();//这里有错误的请求:(Log.v("上传", "成功");} 捕捉(异常前){Log.e("上传错误:", ex.getMessage());}

这是我的 Web Api 方法:

 [路由(上传")][HttpPost]公共 IHttpActionResult 上传(){if (HttpContext.Current.Request.Files.AllKeys.Any()){//从 Files 集合中获取上传的图片var httpPostedFile = HttpContext.Current.Request.Files["file"];如果 (httpPostedFile != null){//验证上传的图片(可选)var 文件夹 = HttpContext.Current.Request.Form["文件夹"];var fileName = HttpContext.Current.Request.Form["name"];文件名 = string.IsNullOrEmpty(fileName) ?httpPostedFile.FileName : 文件名;//获取完整的文件路径var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Files/" + folder), fileName);//将上传的文件保存到UploadedFiles"文件夹httpPostedFile.SaveAs(fileSavePath);return Ok(new OkMessage { Message = "文件上传成功", Path = "/Files/" + folder + "/" + fileName });}}return BadRequest("文件未上传");}

请帮助我错在哪里以及如何实现这一点,有没有简单的改造替代方案?

此代码运行成功,感谢

2) 正确的 POST

Read edit at bottom of the question for possible alternative solution until the solution is found.

This is a successful post file with two parameters using POSTMan. I am trying to do the same with retrofit but receive BadRequest.

PostMan Settings:

Chrome Network Post Details:

Now here is how I am doing this in Android but failing:

Retrofit Service Interface:

@Multipart
@POST("jobDocuments/upload")
Call<ResponseBody> upload(@Part("file") MultipartBody.Part file,@Part("folder") MultipartBody.Part folder,@Part("name") MultipartBody.Part name);

This is my @Background method to run the network request with above service generated

CustDataClient service =
            ServiceGenerator.createService(CustDataClient.class);
    File file = new File(fileUri.getPath());
    // create RequestBody instance from file
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("multipart/form-data"), file);

    MultipartBody.Part fileData =
            MultipartBody.Part.createFormData("file", fileName, requestFile);
    MultipartBody.Part folder =
            MultipartBody.Part.createFormData("folder", "LeadDocuments");
    MultipartBody.Part name =
            MultipartBody.Part.createFormData("name", fileName);
    // finally, execute the request
    Call<ResponseBody> call = service.upload(fileData,folder,name);
    try {
        Response<ResponseBody> rr = call.execute();
        ResponseBody empJobDocsResult = rr.body();//Bad Request here :(
        Log.v("Upload", "success");
    } catch (Exception ex) {
        Log.e("Upload error:", ex.getMessage());
    }

Here is my Web Api Method:

 [Route("upload")]
    [HttpPost]
    public IHttpActionResult Upload()
    {
        if (HttpContext.Current.Request.Files.AllKeys.Any())
        {
            // Get the uploaded image from the Files collection
            var httpPostedFile = HttpContext.Current.Request.Files["file"];

            if (httpPostedFile != null)
            {
                // Validate the uploaded image(optional)
                var folder = HttpContext.Current.Request.Form["folder"];
                var fileName = HttpContext.Current.Request.Form["name"];
                fileName = string.IsNullOrEmpty(fileName) ? httpPostedFile.FileName : fileName;
                // Get the complete file path
                var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Files/" + folder), fileName);

                // Save the uploaded file to "UploadedFiles" folder
                httpPostedFile.SaveAs(fileSavePath);

                return Ok(new OkMessage { Message = "File uploaded successfully", Path = "/Files/" + folder + "/" + fileName });
            }
        }

        return BadRequest("File not uploaded");
    }

Please help where I am wrong and how to achieve this, is there any easy alternative to retrofit?

[Edit] This code is working successfully, Thanks to koush/ion:

Ion.with(getContext())
                            .load("POST", "http://www.dgheating.com/api/jobDocuments/upload")
                            .setMultipartParameter("folder", "LeadDocuments")
                            .setMultipartParameter("name", fileName)
                            .setMultipartFile("file", new File(imagePath))
                            .asJsonObject()
                            .setCallback(...);

解决方案

I faced similar issue here: Android with Retrofit2 OkHttp3 - Multipart POST Error

I got my problem solved after taking @TommySM suggestion. If is still unclear to you, I think this is the solution:

@Multipart
@POST("jobDocuments/upload")
Call<ResponseBody> upload(
    @Part MultipartBody.Part file,
    @Part("folder") RequestBody folder,
    @Part("name")   RequestBody name);

File file = new File(fileUri.getPath());

// Assume your file is PNG
RequestBody requestFile =
        RequestBody.create(MediaType.parse("image/png"), file);

MultipartBody.Part fileData =
        MultipartBody.Part.createFormData("file", fileName, requestFile);

RequestBody folder = RequestBody.create(
        MediaType.parse("text/plain"),
        "LeadDocuments");

RequestBody name = RequestBody.create(
        MediaType.parse("text/plain"),
        fileName);

// finally, execute the request
Call<ResponseBody> call = service.upload(fileData, folder, name);

The important part is to use MediaType.parse("text/plain") for MediaType of String parameter (I believe your case is: folder & name parameter), using okhttp3.MultipartBody.FORM is a mistake.

See these screenshots for the comparison:

1) Problematic POST

2) Correct POST

这篇关于Retrofit 2 无法上传带有两个额外单独字符串参数的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆