C# 使用HttpListener处理POST请求时如何获取带扩展名的文件名
C# HttpListener处理POST请求获取带扩展名文件名方案
原实现问题
- 正则规则仅支持字母数字组成的文件名,遇到中文、空格、下划线、短横线等常用文件名字符时会匹配失败
- 手动解析
multipart/form-data格式容错率极低,无法兼容多文件上传、额外表单字段、文件名特殊编码等场景
推荐方案(官方API解析,稳定兼容)
使用.NET内置的HttpContent相关API直接解析表单内容,不需要手动正则匹配,可兼容绝大多数边界场景:
首先引入对应命名空间:
using System.Net.Http; using System.Text; using System.Web; // 如需处理中文文件名编码可引入
修改ProcessRequest方法实现如下:
private static async void ProcessRequest(HttpListenerContext context) { try { // 校验请求是否为文件上传类型 if (!context.Request.HasEntityBody || !context.Request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase)) { context.Response.StatusCode = 400; context.Response.Close(); return; } string targetFileName = null; // 将请求流包装为HttpContent用于解析 using (var streamContent = new StreamContent(context.Request.InputStream)) { // 注入请求头的Content-Type用于识别边界符 streamContent.Headers.TryAddWithoutValidation("Content-Type", context.Request.ContentType); // 解析多部分表单内容 var multipartContent = await streamContent.ReadAsMultipartAsync(); foreach (var part in multipartContent.Contents) { var disposition = part.Headers.ContentDisposition; // 筛选文件类型的表单项 if (disposition != null && disposition.IsFile && !string.IsNullOrEmpty(disposition.FileName)) { // 去除文件名自带的双引号 targetFileName = disposition.FileName.Trim('"'); // 若存在中文文件名乱码,可添加转码逻辑 // targetFileName = HttpUtility.UrlDecode(targetFileName, Encoding.UTF8); break; } } } // 此处已拿到带扩展名的完整文件名,可按需使用 Console.WriteLine($"提取到文件名:{targetFileName}"); // 原有响应逻辑 byte[] respBytes = Encoding.UTF8.GetBytes("ACK"); context.Response.StatusCode = 200; context.Response.KeepAlive = false; context.Response.ContentLength64 = respBytes.Length; context.Response.OutputStream.Write(respBytes, 0, respBytes.Length); } catch { context.Response.StatusCode = 500; } finally { context.Response.Close(); } }
临时兼容方案(优化正则)
如果项目版本不支持上述API,可优化正则规则提升兼容性:
var body = new StreamReader(context.Request.InputStream).ReadToEnd(); // 适配普通filename和UTF8编码的filename*格式,支持各类常见文件名 var match = Regex.Match(body, @"filename\*?=""?(?<fileName>[^""]+)""?", RegexOptions.IgnoreCase); string fileName = match.Success ? match.Groups["fileName"].Value : string.Empty;
内容的提问来源于stack exchange,提问作者sysOut
相关产品推荐
相关产品推荐

