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

.NET 8 Web API提交大集合遇SocketException问题求助

解决方案:解决.NET 8 Web API提交大列表时的SocketException错误

核心原因

该错误通常是请求体超出服务器/客户端大小限制或请求超时导致连接被强制关闭,1000条数据刚好处于阈值内,更大数据量则触发限制。


1. 调整ASP.NET Core服务器端的请求限制

在Blazor托管的Web API项目中,修改配置以允许更大的请求体:

方式一:全局配置(Program.cs)

// 调整Kestrel服务器的最大请求体大小
builder.Services.Configure<KestrelServerOptions>(options =>
{
    // 按需设置,例如100MB(单位:字节),或设为long.MaxValue允许无限制
    options.Limits.MaxRequestBodySize = 100 * 1024 * 1024;
});

// 若使用IIS托管,需额外配置表单限制
builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 100 * 1024 * 1024;
});

方式二:Action级别的局部配置

直接在API方法上标注限制:

[RequestSizeLimit(100 * 1024 * 1024)] // 100MB
[HttpPost("ImportBranchAppointments/{ApiKey},{BranchCode}")]
public async Task<ActionResult<int>> ImportBranchAppointmentsAsync(...)
{
    // 原有逻辑
}

IIS部署额外配置(web.config)

如果Web API部署在IIS,需修改站点配置文件:

<system.webServer>
  <security>
    <requestFiltering>
      <!-- 100MB,单位字节 -->
      <requestLimits maxAllowedContentLength="104857600" />
    </requestFiltering>
  </security>
</system.webServer>

2. 优化WinForm客户端的请求配置

客户端的默认超时和序列化设置可能无法适配大数据传输:

// 初始化HttpClient时延长超时时间(例如5分钟)
client.Timeout = TimeSpan.FromMinutes(5);

// 优化JSON序列化,减少请求体体积
var jsonOptions = new JsonSerializerOptions
{
    WriteIndented = false, // 关闭缩进减少冗余字符
    IgnoreNullValues = true // 忽略空值字段
};

// 使用优化后的序列化选项发送请求
var Result = await client.PostAsJsonAsync(
    $"api/ImportData/ImportBranchAppointments/{ApiKey},{BranchCode}", 
    Data,
    jsonOptions);

3. 改用流式传输(最优大对象方案)

如果数据量极大,流式传输可避免一次性将所有数据加载到内存,性能和稳定性更优:

服务器端修改

[HttpPost("ImportBranchAppointments/{ApiKey},{BranchCode}")]
public async Task<ActionResult<int>> ImportBranchAppointmentsAsync(
    string ApiKey, 
    string BranchCode, 
    Stream requestStream)
{
    var OrgGuid = ValidateApiKey(ApiKey);
    if (OrgGuid == "")
    {
        return Unauthorized("Invalid API key");
    }

    try
    {
        int importedCount = 0;
        // 流式反序列化,逐行处理数据
        await foreach (var appointment in JsonSerializer.DeserializeAsyncEnumerable<AppointmentModel>(requestStream))
        {
            // 调用服务处理单个预约,或累积到一定批量后提交(如每100条一次)
            await _ImportService.ImportSingleAppointment(ApiKey, BranchCode, appointment);
            importedCount++;
        }
        return Ok(importedCount);
    }
    catch (Exception ex)
    {
        return StatusCode(500, $"Internal server error {ex.Message}");
    }
}

客户端修改

// 流式序列化并发送数据,避免内存过载
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, Data);
stream.Position = 0;

var content = new StreamContent(stream);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

var Result = await client.PostAsync(
    $"api/ImportData/ImportBranchAppointments/{ApiKey},{BranchCode}", 
    content);

4. 启用分块传输编码

客户端启用分块传输,避免一次性发送全部数据:

client.DefaultRequestHeaders.TransferEncodingChunked = true;

服务器端默认支持分块传输,无需额外配置。


方案优先级建议

  1. 先尝试调整请求大小限制+超时,实现成本最低,适合数据量不是极端大的场景;
  2. 若数据量持续增长,流式传输是最优方案,能大幅降低内存占用,避免超时问题;
  3. 分批提交作为备选方案,适合快速临时解决,但长期来看流式传输更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:15:16