JSON ASP.NET Core 3.1 Web API 响应中断,带有自定义响应包装器

JSON response breaks in ASP.NET Core 3.1 Web API with custom response wrapper

我正在开发一个 ASP.NET 2.2 Web API 项目,该项目使用包装器来生成一致的响应。经过一番搜索,我发现该团队遵循了文章“A Custom Wrapper For Managing Exceptions And Consistent Responses”中的实现。

这按预期工作。现在我们正计划升级到 ASP.NET Core 3.1。升级后,这不会按预期工作。我认为这是由于 ASP.NET Core 2.2 和 3.1 之间的重大更改所致。我按照 Microsoft 的 Migrate from ASP.NET Core 2.2 to 3.0 指南修复了所有这些问题。

现在我的 JSON 来自 API 的回复中断了。

响应成功时执行的代码如下:

private static Task HandleSuccessRequestAsync(HttpContext context, object body, int code)  
{  
    context.Response.ContentType = "application/json";  
    string jsonString, bodyText = string.Empty;  
    APIResponse apiResponse = null;  


    if (!body.ToString().IsValidJson())  
        bodyText = JsonConvert.SerializeObject(body);  
    else  
        bodyText = body.ToString();  

    dynamic bodyContent = JsonConvert.DeserializeObject<dynamic>(bodyText);  
    Type type;  

    type = bodyContent?.GetType();  

    if (type.Equals(typeof(Newtonsoft.Json.Linq.JObject)))  
    {  
        apiResponse = JsonConvert.DeserializeObject<APIResponse>(bodyText);  
        if (apiResponse.StatusCode != code)  
            jsonString = JsonConvert.SerializeObject(apiResponse);  
        else if (apiResponse.Result != null)  
            jsonString = JsonConvert.SerializeObject(apiResponse);  
        else  
        {  
            apiResponse = new APIResponse(code, ResponseMessageEnum.Success.GetDescription(), bodyContent, null);  
            jsonString = JsonConvert.SerializeObject(apiResponse);  
        }  
    }  
    else  
    {  
        apiResponse = new APIResponse(code, ResponseMessageEnum.Success.GetDescription(), bodyContent, null);  
        jsonString = JsonConvert.SerializeObject(apiResponse);  
    }  

    return context.Response.WriteAsync(jsonString);  
}  

我一直在调试,直到它命中 HandleSuccessRequestAsync() 方法中的 return context.Response.WriteAsync(jsonString);。一切都很好。但是 JSON 响应中断。

预期响应:

{  
    "Version": "1.0.0.0",  
    "StatusCode": 200,  
    "Message": "Request successful.",  
    "Result": [  
        "value1",  
        "value2"  
    ]  
}  

实际响应:

{  
    "Version": "1.0.0.0",  
    "StatusCode": 200,  
    "Message": "Request successful.",  
    "Result":   

请帮我看看哪里出错了?这是因为 ASP.NET Core 3.1 升级了吗?

我们在使用自定义中间件更改响应的应用程序中遇到了同样的问题 body。此页面很有帮助:

Content Injection with Response Rewriting in ASP.NET Core 3.x

只要在将更改后的 body 写入响应之前将 ContentLength 更改为 null,我们就不必像上页中那样为 HttpResponse.Body 创建包装器。尽管当控制器操作 returns 它的值和响应 body 被写入时,了解什么 ASP.NET Core 2.2 没有设置 ContentLength 是有帮助的,ASP.NET Core 3.1 确实设置了内容长度。结果,当我们更改响应 body 时,内容变得比设置的 ContentLength 更长。

我们有代码在等待控制器操作之前用内存字符串替换响应 body。这是为了能够捕获来自任何控制器方法的响应。然后更改响应并将原始流恢复为响应 object。然后将更改后的响应写入 body 并保留其原始流。

发生的事情是,当中间件等待控制器响应时,响应设置了 ContentLength。然后,当我们写入更改后的响应 body 时,ContentLength 没有更新。所以收到的 json 字符串被截断了。我们能够将 ContentLength 更改为更改内容的长度(或使用 null,两者都有效),IF 我们在 before 写入将 body 更改为响应。