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

.NET 6 API接收大Base64串时末尾被截断的问题求助

解决.NET 6中反序列化大Base64串被截断的问题

问题分析

你遇到的情况是:接口接收包含10MB以上Base64串的JSON请求时,手动读取Request.Body得到的字符串完整,但通过JsonSerializer.Deserialize或[FromBody]绑定得到的DocumentData却出现末尾截断。即使改用string或dynamic类型参数,问题依然存在。

排查与解决方案

1. 先验证:是否真的是数据截断,而非控制台输出限制

控制台窗口默认有输出长度限制,长字符串无法完整显示,容易误以为数据被截断。先通过以下代码验证实际数据长度:

using (var reader = new StreamReader(Request.Body))
{
    var body = await reader.ReadToEndAsync();
    Console.WriteLine($"请求体总长度:{body.Length}");
    
    var result = JsonSerializer.Deserialize<OrderData>(body);
    Console.WriteLine($"DocumentData实际长度:{result.DocumentData?.Length ?? 0}");
    
    // 可选:将完整字符串写入文件验证
    await File.WriteAllTextAsync("documentdata.txt", result.DocumentData);
}

如果DocumentData的长度和请求体中对应字段的长度一致,说明数据并未截断,只是控制台显示不全,改用文件输出或调试工具查看即可。

2. 修复流读取冲突问题

你的代码同时使用了[FromBody]参数绑定和手动读取Request.Body,这会导致流读取冲突:ASP.NET Core会在方法执行前通过[FromBody]读取一次请求流,此时流的位置已处于末尾,后续手动读取可能得到异常结果(即使你现在能读到完整内容,也是依赖流缓冲的不确定行为)。

解决方法二选一:

  • 移除[FromBody]参数,完全手动处理流:
    [HttpPost]
    [Route("Test")]
    public async Task<IActionResult> Test()
    {
        using (var reader = new StreamReader(Request.Body))
        {
            var body = await reader.ReadToEndAsync();
            Console.WriteLine(body);
            
            var result = JsonSerializer.Deserialize<OrderData>(body);
            Console.WriteLine($"DocumentData长度:{result.DocumentData.Length}");
        }
        return Ok();
    }
    
  • 启用请求流缓冲,允许重复读取:
    在方法开头添加流重置代码,确保[FromBody]和手动读取都能正常工作:
    [HttpPost]
    [Route("Test")]
    public async Task<IActionResult> Test([FromBody] OrderData data)
    {
        // 启用缓冲并重置流位置
        Request.EnableBuffering();
        Request.Body.Position = 0;
        
        using (var reader = new StreamReader(Request.Body))
        {
            var body = await reader.ReadToEndAsync();
            Console.WriteLine(body);
            
            var result = JsonSerializer.Deserialize<OrderData>(body);
            Console.WriteLine($"DocumentData长度:{result.DocumentData.Length}");
        }
        return Ok();
    }
    

3. 调整JSON序列化配置(若确为反序列化截断)

如果验证后确认是JsonSerializer反序列化时截断了长字符串,可通过全局配置或局部配置调整序列化选项:

  • 全局配置(Program.cs):
    builder.Services.AddControllers()
        .AddJsonOptions(options =>
        {
            // 提高最大深度限制(默认32,长字符串不涉及深度,但可避免潜在问题)
            options.JsonSerializerOptions.MaxDepth = 64;
            // 禁用严格的Unicode转义,避免特殊字符处理异常
            options.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
        });
    
  • 局部反序列化配置:
    var serializerOptions = new JsonSerializerOptions
    {
        MaxDepth = 64,
        Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
    };
    var result = JsonSerializer.Deserialize<OrderData>(body, serializerOptions);
    

4. 确保请求大小限制足够

若JSON请求整体超过ASP.NET Core默认限制(默认30MB),需调整请求大小限制:

  • 接口级配置:
    [HttpPost]
    [Route("Test")]
    [RequestSizeLimit(100 * 1024 * 1024)] // 允许100MB请求
    public async Task<IActionResult> Test([FromBody] OrderData data)
    {
        // 方法逻辑
    }
    
  • 全局配置(Program.cs):
    builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
    {
        options.ValueLengthLimit = int.MaxValue;
        options.MultipartBodyLengthLimit = 100 * 1024 * 1024;
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:27:33