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

.NET 4.7.1客户端与服务端通过REST传输byte[]问题求助

客户端报错修复与优化实现

问题根源

报错Status Code: 500, ReasonPhrase: 'could not find expected boundary'的核心原因:

  • 错误地将内部文件内容的ContentType设置为multipart/form-data,这个类型属于外层MultipartFormDataContent,文件本身应该用二进制流类型
  • ContentDisposition使用了attachment,表单上传场景下必须用form-data,且要指定name属性供服务端识别
  • Accept头无需复杂设置,只需指定服务端支持的响应类型即可,比如接受任意类型*/*

修正后的客户端代码

HttpClient client = new HttpClient();
// 清除原有Accept头,添加可接受的响应类型
client.DefaultRequestHeaders.Accept.Clear();
// 若服务端返回Location(URI),可直接用*/*表示接受任意响应格式
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));

using (var content = new MultipartFormDataContent())
{
   var fileContent = new ByteArrayContent(bytes);
   // 文件内容设置为二进制流类型
   fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
   // 使用form-data类型的ContentDisposition,指定name(需与服务端解析时对应)
   fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
   {
      Name = "uploadFile",
      FileName = "My.dat"
   };
   content.Add(fileContent);
   var response = await client.PostAsync(url, content);
   response.EnsureSuccessStatusCode();
   return response.Headers.Location;
}

服务端文件接收实现

核心逻辑

通过HttpListenerRequest解析multipart/form-data请求体,提取指定name的文件内容,写入目标文件。需手动处理请求边界,定位文件内容区域。

可靠实现代码

public async Task ReceiveFile(HttpListenerRequest request, string saveFilePath)
{
    if (!request.HasEntityBody)
        return;

    // 验证请求类型并提取边界
    var contentType = request.ContentType;
    if (!contentType.StartsWith("multipart/form-data"))
        throw new InvalidOperationException("请求格式错误,仅支持multipart/form-data");

    var boundaryPart = contentType.Split(';')
        .FirstOrDefault(p => p.Trim().StartsWith("boundary="))?
        .Split('=')[1].Trim();
    if (string.IsNullOrEmpty(boundaryPart))
        throw new InvalidOperationException("无法解析请求边界");

    var boundary = $"--{boundaryPart}";
    var boundaryBytes = request.ContentEncoding.GetBytes(boundary);
    var endBoundaryBytes = request.ContentEncoding.GetBytes($"{boundary}--");

    using (var requestStream = request.InputStream)
    using (var fileStream = new FileStream(saveFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
    {
        byte[] buffer = new byte[8192];
        int bytesRead;
        bool isFileContent = false;
        bool isEnd = false;

        while ((bytesRead = await requestStream.ReadAsync(buffer, 0, buffer.Length)) > 0 && !isEnd)
        {
            if (!isFileContent)
            {
                // 定位到目标文件的form-data块
                var chunk = request.ContentEncoding.GetString(buffer, 0, bytesRead);
                if (chunk.Contains($"name=\"uploadFile\"") && chunk.Contains("filename=\""))
                {
                    // 跳过块头,定位到文件内容起始位置
                    var contentStart = chunk.IndexOf(Environment.NewLine + Environment.NewLine);
                    if (contentStart != -1)
                    {
                        contentStart += 2 * Environment.NewLine.Length;
                        var remaining = bytesRead - contentStart;
                        await fileStream.WriteAsync(buffer, contentStart, remaining);
                        isFileContent = true;
                    }
                }
            }
            else
            {
                // 检查是否到达文件块结束边界
                var chunk = request.ContentEncoding.GetString(buffer, 0, bytesRead);
                var boundaryIndex = chunk.IndexOf(boundary);
                if (boundaryIndex != -1)
                {
                    // 写入边界前的有效内容
                    await fileStream.WriteAsync(buffer, 0, boundaryIndex);
                    isEnd = true;
                }
                else
                {
                    await fileStream.WriteAsync(buffer, 0, bytesRead);
                }
            }
        }
    }
}

注意事项

  • 代码中name="uploadFile"需与客户端设置的Name属性完全一致
  • 建议根据实际场景调整缓冲区大小(当前为8192字节),优化大文件写入性能
  • 可添加异常捕获与日志记录,增强稳定性

内容的提问来源于stack exchange,提问作者Jim C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:43:09