创建双控制器单中间件的.NET Core应用及排查POST请求400错误
问题诊断与解决
核心问题原因
你的中间件代码存在两个关键问题,直接触发了400错误:
- 异步方法未等待:
reader.ReadToEndAsync().ToString()没有使用await关键字,导致requestBody存储的是Task<string>对象的字符串表示,而非实际的请求JSON内容。这不仅让存储的数据无效,还会耗尽请求体流。 - 请求体流未重置:即便正确读取了请求体,你没有重置流的起始位置,后续MVC控制器的模型绑定无法再次读取请求体,进而触发验证错误。
修复后的中间件代码
将Invoke方法改为异步模式,并正确处理请求体流:
public async Task Invoke(HttpContext context) { if (context.Request.Method == "POST" && context.Request.ContentType?.Contains("application/json") == true) { // 启用请求体缓冲,允许后续重复读取 context.Request.EnableBuffering(); string requestBody; using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true)) { requestBody = await reader.ReadToEndAsync(); // 重置流位置到起始点,保证控制器能读取 context.Request.Body.Position = 0; } SaveToJsonFile(requestBody); } await _next(context); } private void SaveToJsonFile(string data) { try { List<object> existingData = new List<object>(); if (File.Exists(filePath)) { var jsonData = File.ReadAllText(filePath); existingData = JsonConvert.DeserializeObject<List<object>>(jsonData); } var newData = JsonConvert.DeserializeObject<object>(data); existingData.Add(newData); File.WriteAllText(filePath, JsonConvert.SerializeObject(existingData, Formatting.Indented)); } catch (Exception ex) { Console.WriteLine("Error saving data: " + ex.Message); } }
额外优化建议
- 确保
filePath是提前初始化的有效路径,避免因路径异常导致隐性错误。 - 生产环境中建议给文件写入操作添加并发锁,防止多请求同时写入引发文件冲突。
- 增加日志记录逻辑,便于后续快速排查类似流处理或数据存储问题。
内容的提问来源于stack exchange,提问作者Melon Bista
相关产品推荐
相关产品推荐

