Retrofit 2 无法上传带有两个额外单独字符串参数的文件 [英] Retrofit 2 can't upload a file with two additional separate string parameters
问题描述
阅读问题底部的编辑以获取可能的替代解决方案,直到找到解决方案.
这是一个使用 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屋!