Grapevine 如何正确解析 Form Data 并实现文件上传
Grapevine 解析Form Data实现单文件上传方案
适配版本
适用于Grapevine 5.x及以上正式版本,解决legacy版本旧方案失效问题。
完整实现代码
using Grapevine; using Microsoft.AspNetCore.WebUtilities; using System.Net; using System.Net.Http.Headers; using System.Text; [RestResource] public class FileUploadResource { [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "/api/file/upload")] public async Task<IHttpResponse> UploadSingleFile(IHttpContext context) { // 校验请求头类型 if (!context.Request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase)) { context.Response.StatusCode = HttpStatusCode.BadRequest; return context.Response.SendResponse("请求格式错误,仅支持multipart/form-data类型"); } // 提取请求边界值 var boundary = MediaTypeHeaderValue.Parse(context.Request.ContentType).Boundary.Trim('"'); var multipartReader = new MultipartReader(boundary, context.Request.InputStream); var section = await multipartReader.ReadNextSectionAsync(); while (section != null) { var contentDisposition = ContentDispositionHeaderValue.Parse(section.ContentDisposition); // 匹配文件字段 if (contentDisposition.DispositionType.Equals("form-data") && !string.IsNullOrWhiteSpace(contentDisposition.FileName.Value)) { // 自定义文件保存路径,可根据业务调整 var saveDir = Path.Combine(AppContext.BaseDirectory, "upload_files"); Directory.CreateDirectory(saveDir); var fullSavePath = Path.Combine(saveDir, contentDisposition.FileName.Value); // 写入本地文件 using (var writeStream = new FileStream(fullSavePath, FileMode.Create, FileAccess.Write)) { await section.Body.CopyToAsync(writeStream); } context.Response.StatusCode = HttpStatusCode.OK; return context.Response.SendResponse($"文件上传成功,保存路径:{fullSavePath}"); } // 如果需要解析普通表单字段,可在这里增加分支处理 // if (contentDisposition.DispositionType.Equals("form-data") // && string.IsNullOrWhiteSpace(contentDisposition.FileName.Value)) // { // using var reader = new StreamReader(section.Body, Encoding.UTF8); // var fieldValue = await reader.ReadToEndAsync(); // var fieldName = contentDisposition.Name.Value; // } section = await multipartReader.ReadNextSectionAsync(); } context.Response.StatusCode = HttpStatusCode.BadRequest; return context.Response.SendResponse("未检测到有效上传文件"); } }
注意事项
- 该实现依赖.NET 自带的
Microsoft.AspNetCore.WebUtilities库,.NET Core 3.1及以上版本默认内置,无需额外安装NuGet包。 - 可根据业务需求扩展文件大小校验、格式白名单校验、重命名文件等逻辑,避免上传风险。
- 若需处理多文件上传,仅需去掉匹配到文件后的return逻辑,持续遍历所有section即可。
内容的提问来源于stack exchange,提问作者ElegantCrab
相关产品推荐
相关产品推荐

