Web API读取POST请求体时 被添加额外斜杠的问题及替代方案咨询
问题分析与解决方案
核心问题出在直接操作JSON字符串的转义结构上:原始请求中的"\t"是JSON规范中的转义表示,对应实际的制表符字符(ASCII 0x09)。但当你用StreamReader读取后直接将字符串写回请求流时,相当于把\和t两个普通字符写入,JSON解析器会将其识别为字符串"\t",而非实际的制表符。
除了手动替换"\t"为制表符的方案,更规范且通用的解决方式是通过JSON序列化库解析请求体为对象,修改后再序列化回JSON,这样转义逻辑会由库自动处理,避免破坏JSON的转义规则。
具体实现(以Newtonsoft.Json为例)
1. 修改请求体读取逻辑,直接解析为JObject
private async Task<JObject> GetRequestBodyAsJObjectAsync(HttpRequest request) { request.EnableBuffering(); request.Body.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true)) { var jsonContent = await reader.ReadToEndAsync(); request.Body.Position = 0; return JObject.Parse(jsonContent); } }
2. 在过滤器中修改JObject并重新序列化
public async Task OnAuthorizationAsync(AuthorizationFilterContext filterContext) { var request = filterContext.HttpContext.Request; if (!request.ContentType?.Contains("application/json") ?? true) { return; // 非JSON请求直接跳过 } // 读取并解析原始请求体为JObject var originalJObj = await GetRequestBodyAsJObjectAsync(request); // 执行你的业务逻辑:向请求体添加内容 originalJObj["additionalField"] = "extraValue"; // 示例:添加新字段 // 如果需要修改已有字段,比如myData: // originalJObj["myData"] = ((string)originalJObj["myData"]) + " appended text"; // 将修改后的JObject序列化为正确的JSON字符串(自动处理转义) var modifiedJson = originalJObj.ToString(Formatting.None); // 重新生成请求流并替换 var newStream = new MemoryStream(Encoding.UTF8.GetBytes(modifiedJson)); request.Body = newStream; request.ContentLength = newStream.Length; }
为什么这个方案更好?
- 自动处理所有JSON转义字符(如
\n、\"、\r等),无需手动逐个替换,避免遗漏或错误。 - 基于对象的修改更直观,不易破坏JSON结构(比如语法错误)。
- 适配复杂的JSON嵌套结构,手动字符串操作在这种场景下极易出错。
可选:使用System.Text.Json(.NET Core原生库)
如果项目使用原生的System.Text.Json,可以用JsonDocument和JsonElement来处理:
private async Task<JsonElement> GetRequestBodyAsJsonElementAsync(HttpRequest request) { request.EnableBuffering(); request.Body.Seek(0, SeekOrigin.Begin); using (var doc = await JsonDocument.ParseAsync(request.Body)) { request.Body.Position = 0; return doc.RootElement.Clone(); } } // 在OnAuthorizationAsync中修改: var originalElement = await GetRequestBodyAsJsonElementAsync(request); var modifiedObj = JsonSerializer.Deserialize<Dictionary<string, object>>(originalElement.GetRawText()); modifiedObj["additionalField"] = "extraValue"; var modifiedJson = JsonSerializer.Serialize(modifiedObj); // 后续替换流逻辑同上
内容的提问来源于stack exchange,提问作者Imran Khan
相关产品推荐
相关产品推荐

