.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
相关产品推荐
相关产品推荐

