Web API 中的读取 POST 请求正文正在向 ' ' 添加额外的斜杠

问题描述 投票:0回答:1

我们有一个要求,对于某个休息调用,我们需要在将请求发送到控制器之前拦截请求并向请求正文添加一些内容。我可以使用授权过滤器来做到这一点。问题是,当我使用流读取器读取请求时,它以某种方式向“ ”(选项卡)添加了一个额外的斜杠。这使得它''。当请求到达控制器时,由于这个额外的斜杠,它被视为文本而不是“tab”。

请求正文

{
"myData": "This is some text \t more text"
}

控制器

[MyRequestConverter]
[HttpPost]
public virtual IActionResult myServiceAction([FromBody]myRequestModel myRequest)
{  
   // suppose print is something that writes the data to a file
   print(myRequest.myData);
}

授权过滤器

public class MyRequestConverter : Attribute, IAsyncAuthorizationFilter
 {

     public MyRequestConverter() { }

     private async Task<string> GetRequestBodyAsTextAsync(HttpRequest request)
     {    
        
             var reqbody = "";
             request.EnableBuffering();
             request.Body.Seek(0, SeekOrigin.Begin);

             using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
             {
                 reqbody = await @reader.ReadToEndAsync();
             }
             request.Body.Position = 0;

             return reqbody;

     }


     public async Task OnAuthorizationAsync(AuthorizationFilterContext filterContext)
     {
                var stream = request.Body;// currently holds the original stream                    

                var originalContent = await GetRequestBodyAsTextAsync(request);

                originalContent = AddSomethingToRequestBody(originalContent);

               var requestContent = new StringContent(originalContent, Encoding.UTF8, "application/json");
               stream = await requestContent.ReadAsStreamAsync();

                var requestData = Encoding.UTF8.GetBytes(originalContent);
                stream = new MemoryStream(requestData);

                filterContext.HttpContext.Request.Body = stream;

       }



 }

使用“MyRequestConverter”,它会打印(由于额外的斜杠,它被视为文本)

这是一些文字更多文字

没有“MyRequestConverter”,它会打印(所需的输出 - 它有制表符间距)

这是一些文字(选项卡)更多文字

我做了一些搜索,看起来一个选项是将 '\t' 替换为 ' ',但是这个问题还有其他解决方案吗?

c# asp.net-core http-post streamreader iauthorizationfilter
1个回答
0
投票

使用 JsonDocument.Parse(originalContent) 这样它会再次暂停到 json。最后它将像所需的输出一样输出,即这是一些文本(选项卡)更多文本

这是测试代码

public async Task OnAuthorizationAsync(AuthorizationFilterContext filterContext)
{
    var request = filterContext.HttpContext.Request; // Correctly access the request
 
    // Retrieve the original content of the request body
    var originalContent = await GetRequestBodyAsTextAsync(request);
 
    // Parse the original content as JSON
    using (var jsonDoc = JsonDocument.Parse(originalContent))
    {
        // Clone the root element to modify
        JsonElement root = jsonDoc.RootElement.Clone();
 
        string newMyDataValue = ""; 
 
        // Check if "MyData" property exists and append the additional content
        if (root.TryGetProperty("myData", out JsonElement myData))
        {
            // Append additional content to the existing value
            newMyDataValue = myData.GetString() + " your additional content here";
        }
        else
        {
            // If "MyData" was not found, just use the additional content
            newMyDataValue = "your additional content here";
        }
 
        // Create a new JSON object with the modified "MyData"
        using (var stream = new MemoryStream())
        {
            using (var writer = new Utf8JsonWriter(stream))
            {
                writer.WriteStartObject();
                foreach (var property in root.EnumerateObject())
                {
                    // Write all the existing properties
                    property.WriteTo(writer);
                }
                // Overwrite the "MyData" property with the new value
                writer.WriteString("myData", newMyDataValue);
                writer.WriteEndObject();
            }
 
            // Convert the modified content back into a stream and replace the original request body
            var modifiedRequestBody = stream.ToArray();
            request.Body = new MemoryStream(modifiedRequestBody); // Set the modified stream as the request body
            request.ContentLength = modifiedRequestBody.Length; // Update the Content-Length header
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.