You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:45:02