基于Minimal API的文件上传:C#客户端调用难题
解决Minimal API文件仓库的两个问题:C#客户端上传与检索返回额外数据
一、C#客户端调用带TenantID的文件上传接口
假设你的Minimal API上传接口定义如下(可根据实际参数位置调整):
// Minimal API 上传接口示例 app.MapPost("/files/upload/{tenantId}", async (string tenantId, IFormFile file) => { // 租户隔离存储逻辑 var storedFileId = Guid.NewGuid().ToString(); // 执行文件存储操作... return Results.Ok(new { FileId = storedFileId }); });
C#客户端使用HttpClient调用时,需通过MultipartFormDataContent构造表单数据,同时传递TenantID:
using var httpClient = new HttpClient(); var tenantId = "目标租户ID"; var filePath = @"本地文件路径"; // 构造多部分表单内容 using var content = new MultipartFormDataContent(); // 添加文件流 using var fileStream = new FileStream(filePath, FileMode.Open); var fileContent = new StreamContent(fileStream); fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // 按实际文件类型调整 content.Add(fileContent, "file", Path.GetFileName(filePath)); // 发送请求(TenantID作为路由参数) var response = await httpClient.PostAsync($"https://你的API地址/files/upload/{tenantId}", content); response.EnsureSuccessStatusCode(); // 解析返回的文件ID var result = await response.Content.ReadFromJsonAsync<FileUploadResult>(); Console.WriteLine($"上传成功,文件ID:{result.FileId}"); // 定义返回模型 public class FileUploadResult { public string FileId { get; set; } }
如果TenantID是通过表单参数传递(接口用[FromForm] string tenantId),需在Multipart内容中添加:
content.Add(new StringContent(tenantId), "tenantId");
二、检索接口返回文件时附带额外数据
你提到的Results.File仅返回文件内容的问题,在.NET 8之前可通过以下两种方案解决:
方案1:将元数据放入响应头(推荐)
修改检索接口,在返回文件前添加自定义响应头存储元数据:
app.MapGet("/files/{tenantId}/{fileId}", async (string tenantId, string fileId) => { var storeLocation = Path.Combine("tenants", tenantId, fileId); var mimeType = "application/octet-stream"; // 按实际文件类型设置 var fileResult = Results.File(storeLocation, mimeType); // 添加自定义响应头 fileResult.HttpContext.Response.Headers.Add("X-File-Id", fileId); fileResult.HttpContext.Response.Headers.Add("X-Tenant-Id", tenantId); fileResult.HttpContext.Response.Headers.Add("X-Content-Type", mimeType); return fileResult; });
客户端调用时,先读取响应头再获取文件内容:
using var httpClient = new HttpClient(); var tenantId = "目标租户ID"; var fileId = "目标文件ID"; var response = await httpClient.GetAsync($"https://你的API地址/files/{tenantId}/{fileId}"); response.EnsureSuccessStatusCode(); // 读取元数据 var returnedFileId = response.Headers.GetValues("X-File-Id").FirstOrDefault(); var returnedTenantId = response.Headers.GetValues("X-Tenant-Id").FirstOrDefault(); var mimeType = response.Content.Headers.ContentType?.MediaType; // 读取文件内容 var fileContent = await response.Content.ReadAsByteArrayAsync(); // 执行保存或处理操作...
方案2:返回包含元数据与Base64文件的JSON(仅适合小文件)
若文件体积较小,可将文件转为Base64字符串,与元数据一起返回JSON:
app.MapGet("/files/{tenantId}/{fileId}", async (string tenantId, string fileId) => { var storeLocation = Path.Combine("tenants", tenantId, fileId); var mimeType = "application/octet-stream"; var fileBytes = await File.ReadAllBytesAsync(storeLocation); var base64Content = Convert.ToBase64String(fileBytes); return Results.Ok(new { FileId = fileId, TenantId = tenantId, MimeType = mimeType, FileContent = base64Content }); });
客户端解析后转回字节数组:
var result = await response.Content.ReadFromJsonAsync<FileRetrievalResult>(); var fileBytes = Convert.FromBase64String(result.FileContent); // 处理文件内容... public class FileRetrievalResult { public string FileId { get; set; } public string TenantId { get; set; } public string MimeType { get; set; } public string FileContent { get; set; } }
内容的提问来源于stack exchange,提问作者MisterA
相关产品推荐
相关产品推荐

