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

.NET4.7.5中如何通过POST请求同时发送文件与自定义类?

.NET4.7.5下通过WebRequest同时上传STL文件与自定义类的实现问题
  • 需求:通过WebRequest发起HttpPost请求,同时发送固定路径(C:/Temp/Part.stl)的.stl文件和一个自定义类对象,期望请求为多部分表单格式,同时包含文件流与自定义类的结构化数据。
  • 限制:必须使用.NET4.7.5框架,无法切换到其他版本。
  • 现状:已知.NET6的WebApi中可通过FileContentResult及ControllerBase.File()实现类似功能,但未找到.NET4.7.5的对应实现方式,当前编写的代码无法满足需求。

当前.NET4.7.5实现代码(结合NLogger)

private static bool PingServer(string server, object seDocument)
{
    HttpWebRequest webRequest = WebRequest.CreateHttp($"http://{server}//stl");
    webRequest.Timeout = 5000; //Default is 100.000 (100 seconds)...
    webRequest.Method = WebRequestMethods.Http.Post;


    Byte[] stlFile = System.IO.File.ReadAllBytes($@"{listTempFiles[0]}");
    String base64String = Convert.ToBase64String(stlFile);

    //Note to future me, this doesn't need to be jsonified
    var json = JsonConvert.SerializeObject(seDocument);
    byte[] b = Encoding.UTF8.GetBytes(json);

    switch (System.IO.Path.GetExtension(listTempFiles[0]))
    {
        case ".stl":
        case ".STL":
            webRequest.ContentType = "application/sla";
            break;

        case ".jt":
        case ".JT":
            webRequest.ContentType = ".";
            break;

        default:
            webRequest.ContentType = "application/json";
            break;
    }
    webRequest.ContentLength = b.Length;

    using (var stream = webRequest.GetRequestStream())
    {
        stream.Write(b, 0, b.Length);
    }

    HttpWebResponse response;
    try
    {
        response = webRequest.GetResponse() as HttpWebResponse;
    }
    catch (Exception e)
    {
        LogManager.GetCurrentClassLogger().Info(e.Message);
        return false;
    }

    if (response != null)
    {
        LogManager.GetCurrentClassLogger()
        .Info($"'{server}' responded with status '{response.StatusCode.ToString()}'");
    }

    return response == null || response.StatusCode == HttpStatusCode.OK;
}

.NET6 WebApi参考实现代码

[HttpGet("{mainpath}/{true}")]
public List<MendixFile> GetAll(string mainpath)
{
  List<MendixFile> mendixFiles = new List<MendixFile>();

  string[] files = Directory.GetFiles(mainpath, "*", searchOption: SearchOption.AllDirectories);
  foreach (string file in files)
    {
       Byte[] b = System.IO.File.ReadAllBytes($@"{file}");
       string path = Path.GetDirectoryName(file);
       string name= Path.GetFileName(file);
       MendixFile mendixFile = new MendixFile(path, name, b);
       File(b, "image/jpg");
       mendixFiles.Add(mendixFile);
    }
    return mendixFiles;
}

解决方案(.NET4.7.5下实现多部分表单上传)

要同时发送文件和自定义类,需要构造multipart/form-data格式的请求,这是上传混合数据的标准格式,.NET4.7.5可通过手动拼接边界符、表单字段和文件流实现:

private static bool PingServer(string server, object seDocument)
{
    var boundary = $"----WebKitFormBoundary{Guid.NewGuid():N}";
    HttpWebRequest webRequest = WebRequest.CreateHttp($"http://{server}/stl");
    webRequest.Timeout = 5000;
    webRequest.Method = WebRequestMethods.Http.Post;
    webRequest.ContentType = $"multipart/form-data; boundary={boundary}";

    // 读取固定路径的STL文件
    byte[] stlFileBytes = System.IO.File.ReadAllBytes(@"C:/Temp/Part.stl");
    // 序列化自定义类为JSON
    string seDocJson = JsonConvert.SerializeObject(seDocument);

    using (var requestStream = webRequest.GetRequestStream())
    using (var writer = new StreamWriter(requestStream, Encoding.UTF8))
    {
        // 写入自定义类表单字段
        writer.WriteLine($"--{boundary}");
        writer.WriteLine("Content-Disposition: form-data; name=\"seDocument\"");
        writer.WriteLine("Content-Type: application/json");
        writer.WriteLine();
        writer.Write(seDocJson);
        writer.WriteLine();

        // 写入STL文件字段
        writer.WriteLine($"--{boundary}");
        writer.WriteLine("Content-Disposition: form-data; name=\"stlFile\"; filename=\"Part.stl\"");
        writer.WriteLine("Content-Type: application/sla");
        writer.WriteLine();
        writer.Flush(); // 确保文本内容写入流
        requestStream.Write(stlFileBytes, 0, stlFileBytes.Length);
        writer.WriteLine();

        // 写入结束边界
        writer.WriteLine($"--{boundary}--");
        writer.Flush();
    }

    HttpWebResponse response;
    try
    {
        response = webRequest.GetResponse() as HttpWebResponse;
    }
    catch (Exception e)
    {
        LogManager.GetCurrentClassLogger().Info(e.Message);
        return false;
    }

    if (response != null)
    {
        LogManager.GetCurrentClassLogger()
            .Info($"'{server}' responded with status '{response.StatusCode.ToString()}'");
        response.Close();
    }

    return response != null && response.StatusCode == HttpStatusCode.OK;
}

关键说明

  • 原代码仅发送了自定义类的JSON数据,未包含STL文件,且ContentType设置错误(需用multipart/form-data而非单一的application/sla或application/json)
  • 构造multipart/form-data时需严格遵循格式:每个数据块以边界符开头,包含Content-Disposition和Content-Type头,最后以--边界符--结束
  • 写入流时需先Flush文本内容,再写入二进制文件流,避免编码冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:05:42