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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:42:02