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

C#.NET RESTful服务发送大附件时出现500错误求助

解决大附件(>3MB)通过Web服务发送邮件的请求失败问题

我看你遇到的核心问题是:WinForm端把附件转成Byte[]序列化到JSON后调用Web服务,一旦附件超过3MB就会在HttpWebResponse oWebResp = myReq.GetResponse()处报错,即便已经调整了maxAllowedContentLength也无效。这是因为你只配置了IIS层面的限制,ASP.NET本身还有额外的请求大小限制,同时用JSON传输大二进制数据也不是最优方案,咱们一步步来解决:

1. 补全ASP.NET的请求大小限制配置

maxAllowedContentLength是IIS层面的限制,但传统ASP.NET(你的代码基于.NET Framework)还有自身的maxRequestLength限制,必须同时配置才能生效:

在Web.config中添加/修改以下配置:

<system.web>
  <!-- 单位为KB,这里设置为50MB,executionTimeout延长超时时间避免传输中断 -->
  <httpRuntime maxRequestLength="51200" executionTimeout="300" />
</system.web>
<system.webServer>
  <security>
    <requestFiltering>
      <!-- 单位为Bytes,这里设置为50MB,和上面的maxRequestLength数值匹配 -->
      <requestLimits maxAllowedContentLength="52428800" />
    </requestFiltering>
  </security>
</system.webServer>

2. 优化大二进制数据的传输方式(推荐方案)

把Byte[]序列化为JSON的效率极低,还容易触发各种大小限制,更合理的方式是用multipart/form-data分块上传文件,避免把二进制数据塞进JSON里:

修改WinForm端代码,改用multipart/form-data上传

public void SendEmail(String sender, String recipient, String subject, String htmlBody, String fileLocation, String AttachemntNewName)
{
    string apiUrl = "http://ADDRESS_TO_SERVER/Home/SendMail";
    HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(apiUrl);
    myReq.Method = "POST";
    // 定义multipart分隔符
    string boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
    myReq.ContentType = $"multipart/form-data; boundary={boundary}";
    myReq.Timeout = 60000; // 延长超时时间到60秒
    myReq.Credentials = CredentialCache.DefaultCredentials;

    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    {
        // 写入邮件文本字段
        writer.WriteLine($"--{boundary}");
        writer.WriteLine("Content-Disposition: form-data; name=\"Sender\"");
        writer.WriteLine();
        writer.WriteLine(sender);

        writer.WriteLine($"--{boundary}");
        writer.WriteLine("Content-Disposition: form-data; name=\"Recipient\"");
        writer.WriteLine();
        writer.WriteLine(recipient);

        writer.WriteLine($"--{boundary}");
        writer.WriteLine("Content-Disposition: form-data; name=\"Subject\"");
        writer.WriteLine();
        writer.WriteLine(subject);

        writer.WriteLine($"--{boundary}");
        writer.WriteLine("Content-Disposition: form-data; name=\"HtmlBody\"");
        writer.WriteLine();
        writer.WriteLine(htmlBody);

        // 处理附件(如果存在)
        if (!string.IsNullOrEmpty(fileLocation))
        {
            var fileName = string.IsNullOrEmpty(AttachemntNewName) ? Path.GetFileName(fileLocation) : AttachemntNewName;
            var fileExt = Path.GetExtension(fileName).ToLower();
            var mimeType = MimeTypesAutoGet(fileExt);

            writer.WriteLine($"--{boundary}");
            writer.WriteLine($"Content-Disposition: form-data; name=\"FileBinary\"; filename=\"{fileName}\"");
            writer.WriteLine($"Content-Type: {mimeType}");
            writer.WriteLine();
            writer.Flush();

            // 写入文件二进制数据
            using (var fileStream = new FileStream(fileLocation, FileMode.Open))
            {
                fileStream.CopyTo(stream);
            }
            writer.WriteLine();
        }

        // 结束分隔符
        writer.WriteLine($"--{boundary}--");
        writer.Flush();
        stream.Position = 0;

        myReq.ContentLength = stream.Length;
        using (var reqStream = myReq.GetRequestStream())
        {
            stream.CopyTo(reqStream);
        }

        try
        {
            using (HttpWebResponse oWebResp = myReq.GetResponse() as HttpWebResponse)
            {
                // 可在此处添加响应状态检查逻辑
            }
        }
        catch (WebException Ex)
        {
            MessageBox.Show(Ex.ToString());
        }
    }
}

修改Web服务控制器,接收multipart/form-data请求

public class HomeController : Controller
{
    private IMailer _mailer = new Mailer();

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult SendMail()
    {
        var emailContentDto = new EmailContentDto
        {
            Sender = Request.Form["Sender"],
            Recipient = Request.Form["Recipient"],
            Subject = Request.Form["Subject"],
            HtmlBody = Request.Form["HtmlBody"]
        };

        // 处理上传的附件
        if (Request.Files.Count > 0)
        {
            var uploadedFile = Request.Files[0];
            if (uploadedFile.ContentLength > 0)
            {
                using (var ms = new MemoryStream())
                {
                    uploadedFile.InputStream.CopyTo(ms);
                    emailContentDto.FileBinary = ms.ToArray();
                    emailContentDto.FileName = uploadedFile.FileName;
                    emailContentDto.FileFormat = uploadedFile.ContentType;
                }
            }
        }

        _mailer.SendMail(emailContentDto);
        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
}

3. 其他需要注意的细节

  • 延长SmtpClient的超时时间:你当前设置的80秒对于大附件发送可能不够,可以调整到120秒以上
  • 确保Web服务所在服务器有足够的内存和临时磁盘空间,用于处理大文件上传
  • WinForm端的HttpWebRequest超时时间要和文件大小匹配,避免传输中途超时

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:53:55