.NET 5 Azure Functions从HttpRequestData读取multipart/form-data参数报错
问题根因
- 手动实例化的
StreamContent对象未继承原HTTP请求的Content-Type请求头,ReadAsMultipartAsync方法只能从传入的HttpContent对象的头中读取内容类型,不会读取原HttpRequestData的头,因此触发类型校验失败异常 - 现有代码存在语法错误:代码中调用
ReadAsMultipartAsync的stream变量未声明,实际声明的变量名为contentStream;方法使用了await关键字但未添加async修饰符 - 流资源释放时机不合理,可能在读取未完成时就释放流导致后续操作异常
修复后可运行代码
需提前安装NuGet包Microsoft.AspNet.WebApi.Client
/* Azure Function, HTTP Trigger, .NET 5 Isolated : Update.cs */ [Function("Update")] public static async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext executionContext) { Dictionary<string, string> formDataDict = new Dictionary<string, string>(); // 实例化StreamContent并复制原请求的Content-Type头 using var contentStream = new StreamContent(req.Body); if (req.Headers.TryGetValues("Content-Type", out var contentTypeValues)) { contentStream.Headers.TryAddWithoutValidation("Content-Type", contentTypeValues.First()); } // 解析multipart/form-data内容 var multipartProvider = await contentStream.ReadAsMultipartAsync(); foreach (var httpContent in multipartProvider.Contents) { var formData = await httpContent.ReadAsFormDataAsync(); foreach (string key in formData.AllKeys) { if (!string.IsNullOrEmpty(key)) { formDataDict.TryAdd(key, formData[key]); } } } // 后续业务逻辑,构造返回值示例 var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteAsJsonAsync(new { Success = true, FormData = formDataDict }); return response; }
轻量替代实现(无需依赖Microsoft.AspNet.WebApi.Client包)
可使用.NET自带的MultipartReader完成解析,仅需引用命名空间Microsoft.AspNetCore.WebUtilities
[Function("Update")] public static async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext executionContext) { Dictionary<string, string> formDataDict = new Dictionary<string, string>(); var contentType = req.Headers.GetValues("Content-Type").FirstOrDefault(); var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(contentType).Boundary).Value; var reader = new MultipartReader(boundary, req.Body); var section = await reader.ReadNextSectionAsync(); while (section != null) { var hasContentDisposition = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); if (hasContentDisposition && contentDisposition.IsFormDisposition()) { var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value; using var streamReader = new StreamReader(section.Body); var value = await streamReader.ReadToEndAsync(); formDataDict.TryAdd(key, value); } section = await reader.ReadNextSectionAsync(); } var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteAsJsonAsync(new { Success = true, FormData = formDataDict }); return response; }
内容的提问来源于stack exchange,提问作者Belle 'Sandon' Ling
相关产品推荐
相关产品推荐

