要在ASP.Net Core Web API中上传文件,需要在Controller中提供上传方法,一般为Post类型。这时候客户端一般使用MultipartFormDataContent作为上传内容,可以设置token以及一些和文件相关的参数。在ControllerBase中,可以通过HttpContext.Request.Form.TryGetValue方法获取参数内容,在HttpContext.Request.Form.Files中获取上传的文件列表。
1、Controller代码
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using CommonUploadService.Models; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace CommonUploadService.Controllers { /// <summary> /// 文件上传控制器 /// </summary> [ApiController] [Route("api/v1/[controller]/[action]")] [ApiExplorerSettings(GroupName = nameof(ApiVersion.V1))] public class FileUploadController : ControllerBase { private readonly ILogger<DefectUploadController> _logger; private readonly string _absolutePath; private static readonly string UploadFilePath = @"UploadFile"; public FileUploadController(ILogger<DefectUploadController> logger, IWebHostEnvironment webHostEnvironment) { _logger = logger; var webRootPath = webHostEnvironment.WebRootPath; _absolutePath = Path.Combine(webRootPath, UploadFilePath); if (!Directory.Exists(_absolutePath)) { Directory.CreateDirectory(_absolutePath); } } //http://localhost:5000/api/v1/FileUpload/Upload [HttpPost] public async Task<ActionResult<string>> Upload() { HttpContext.Request.Form.TryGetValue("GroupId", out var groupId); _logger.LogDebug($@"Receive file form group: {groupId}."); if (string.IsNullOrWhiteSpace(groupId)) { _logger.LogError(@"GroupId is null or white space."); return @"Error: GroupId is null or white space."; } var groupPath = Path.Combine(_absolutePath, groupId); if (!Directory.Exists(groupPath)) { try { Directory.CreateDirectory(groupPath); } catch (Exception e) { var message = $@"Create Group Directory failed: {e.Message}."; _logger.LogError(message); return $@"Error: {message}."; } } var fileNames = new List<string>(); var files = HttpContext.Request.Form.Files; foreach (var file in files) { var fileName = file.FileName; _logger.LogDebug($@"Receive file: {fileName}."); try { var filePath = Path.Combine(groupPath, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } fileNames.Add(filePath); } catch (Exception e) { _logger.LogError($@"Copy file [{fileName}] failed: {e.Message}."); } } var sb = new StringBuilder(); foreach (var fileName in fileNames) { sb.Append($@"{fileName}, "); } var filesString = sb.ToString().TrimEnd().TrimEnd(','); _logger.LogInformation($@"收到文件:groupId = {groupId}, fileNames = {filesString}."); return fileNames.Count > 0 ? @"OK" : @"Error"; } } }
2、客户端(Winform/WPF)上传方法
public bool UploadFile(string groupId, List<string> filePathList) { using (var httpClient = new HttpClient()) { var content = new MultipartFormDataContent { {new StringContent(groupId), "\"GroupId\""} }; foreach (var filePath in filePathList) { var fileInfo = new FileInfo(filePath); if (!fileInfo.Exists) { LogHelper.Warn($@"File not exists: {filePath}."); return false; } content.Add(new ByteArrayContent( File.ReadAllBytes(filePath)), "\"file\"", //该参数 form 中的name属性值,和 服务器端 必须对应起来 $"\"{fileInfo.Name}\""); } var response = httpClient.PostAsync(_serverUrl, content).Result; var ret = response.Content.ReadAsStringAsync().Result; LogHelper.Info($@"Upload group file [{groupId}] result: {ret}."); return ret.ToUpper() == @"OK"; } }