Android使用Retrofit上传含图片的ClassA至.NET API技术咨询
问题1:Android端Java与.NET API端的image字段对应类型
- Android端Java:
实体类中可保留File类型用于本地文件引用,但上传时需将其转换为MultipartBody.Part(封装文件流、文件名等上传信息)或RequestBody(指定媒体类型如image/*)。若要直接在实体类适配上传逻辑,也可将ClassB的image字段改为RequestBody。 - .NET API端:
对应类型为IFormFile,这是ASP.NET Core专门用于接收上传文件的类型,包含文件流、文件名、内容类型等核心信息。嵌套列表中的文件直接在ClassB模型中定义为IFormFile即可。
问题2:Retrofit接口定义
由于请求包含文件,必须采用Multipart表单请求,接口定义及参数构建方式如下:
核心接口定义
import okhttp3.MultipartBody; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Multipart; import retrofit2.http.POST; import retrofit2.http.Part; public interface UploadApi { @Multipart @POST("api/upload") // 替换为实际API路径 Call<ResponseBody> uploadClassA(@Part List<MultipartBody.Part> allParts); }
动态构建请求参数示例
如果ClassB的数量是动态的,手动构建所有表单部分:
// 构建基础字段 RequestBody itemA = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(classA.getItemA())); RequestBody itemB = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(classA.getItemB())); List<MultipartBody.Part> allParts = new ArrayList<>(); allParts.add(MultipartBody.Part.createFormData("itemA", null, itemA)); allParts.add(MultipartBody.Part.createFormData("itemB", null, itemB)); // 遍历ClassB列表,逐个构建字段与文件 for (int i = 0; i < classA.getClassB().size(); i++) { ClassB b = classA.getClassB().get(i); // 添加字符串字段 RequestBody aBody = RequestBody.create(MediaType.parse("text/plain"), b.getA()); allParts.add(MultipartBody.Part.createFormData("classBList[" + i + "].a", null, aBody)); RequestBody bBody = RequestBody.create(MediaType.parse("text/plain"), b.getB()); allParts.add(MultipartBody.Part.createFormData("classBList[" + i + "].b", null, bBody)); // 添加文件 RequestBody imageBody = RequestBody.create(MediaType.parse("image/*"), b.getImage()); MultipartBody.Part imagePart = MultipartBody.Part.createFormData( "classBList[" + i + "].Image", b.getImage().getName(), imageBody ); allParts.add(imagePart); } // 发起请求 UploadApi api = RetrofitClient.getInstance().create(UploadApi.class); Call<ResponseBody> call = api.uploadClassA(allParts);
问题3:.NET API接收实现
1. 定义对应模型类
public class ClassA { public int ItemA { get; set; } public int ItemB { get; set; } public List<ClassB> ClassBList { get; set; } } public class ClassB { public string A { get; set; } public string B { get; set; } public IFormFile Image { get; set; } }
2. 控制器接口实现
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; [Route("api/[controller]")] [ApiController] public class UploadController : ControllerBase { [HttpPost("upload")] public IActionResult UploadClassA([FromForm] ClassA model) { // 参数验证 if (model == null || model.ClassBList == null || !model.ClassBList.Any()) { return BadRequest("无效的上传参数"); } // 文件保存逻辑示例 var uploadDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads"); if (!Directory.Exists(uploadDir)) { Directory.CreateDirectory(uploadDir); } foreach (var classB in model.ClassBList) { if (classB.Image != null && classB.Image.Length > 0) { var savePath = Path.Combine(uploadDir, classB.Image.FileName); using (var stream = new FileStream(savePath, FileMode.Create)) { classB.Image.CopyTo(stream); } } } // 处理其他业务逻辑 return Ok(new { Message = "上传成功", ReceivedData = model }); } }
额外配置(大文件上传场景)
若需支持大文件上传,需在Program.cs中调整表单大小限制:
builder.Services.Configure<FormOptions>(options => { options.MultipartBodyLengthLimit = 104857600; // 限制为100MB,可按需调整 });
内容的提问来源于stack exchange,提问作者حسام عليان
相关产品推荐
相关产品推荐

