C# 从.NET core 2.2迁移到3.1 api后,将newtonsoft添加到项目时,结果中间件会中断

C# 从.NET core 2.2迁移到3.1 api后,将newtonsoft添加到项目时,结果中间件会中断,c#,.net,json,C#,.net,Json,因此,我们有一个中间件,它获取API响应的响应体,并将其包装在“data”属性下的ApiResult类中 namespace Web.Api.ApiResult { public class ApiResultMiddleware { private readonly RequestDelegate next; public ApiResultMiddleware(RequestDelegate next) {

因此,我们有一个中间件,它获取API响应的响应体,并将其包装在“data”属性下的ApiResult类中

    namespace Web.Api.ApiResult
{
    public class ApiResultMiddleware
    {
        private readonly RequestDelegate next;

        public ApiResultMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            var originalBody = context.Response.Body;
            var responseBody = string.Empty;
            try
            {
                CsWebException exception = null;

                using (var stream = new MemoryStream())
                {
                    context.Response.Body = stream;

                    try
                    {
                        await next.Invoke(context);
                    }
                    catch (CsWebException e)
                    {
                        exception = e;
                    }

                    stream.Position = 0;
                    responseBody = new StreamReader(stream).ReadToEnd();
                }

                object result = null;

                if (exception != null)
                {
                    result = new ApiResultResponse(null)
                    {
                        ErrorCode = exception.ErrorCode,
                        ErrorData = exception.ErrorData,
                    };
                    context.Response.StatusCode = (int)ApiResultHttpStatusCodeConverter.ConvertToHttpStatusCode(exception.ErrorCode);
                }
                else
                {
                    var data = JsonConvert.DeserializeObject(responseBody);
                    result = new ApiResultResponse(data);
                }

                var buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(
                    result,
                    new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }));
                if (context.Response.StatusCode != StatusCodes.Status204NoContent)
                {
                    using (var output = new MemoryStream(buffer))
                    {
                        var test = JsonConvert.DeserializeObject<ApiResultResponse>(new StreamReader(output).ReadToEnd());
                        await output.CopyToAsync(originalBody);
                    }
                }
            }
            catch (JsonReaderException)
            {
                var result = new ApiResultResponse(responseBody);
                var buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(
                    result,
                    new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }));
                using (var output = new MemoryStream(buffer))
                {
                    await output.CopyToAsync(originalBody);
                }
            }
            finally
            {
                context.Response.Body = originalBody;
            }
        }
    }

    public static class ApiResultMiddlewareExtensions
    {
        public static IApplicationBuilder UseApiResultMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<ApiResultMiddleware>();
        }
    }
}

返回的JSON在中间的某个地方被剪切。在编写JSON之前,我添加了测试变量并反序列化了JSON,它看起来不错,但在前端解析I时却不是这样

例如,写入主体的json如下所示:

"{\"errorCode\":0,\"errorData\":null,\"data\":{\"previousWorkingDayWorkOrders\":[],\"nextWorkingDayWorkOrders\":[],\"todaysWorkOrders\":[],\"nonInvoicedWorkOrders\":[{\"workOrderId\":1232753.0,\"employeeNumber\":5000000037.0,\"employeeName\":\"VERKADM, VERKADM\",\"vehicleRegistrationNumber\":\"PXG948\",\"dealerOrderNumber\":null,\"bookingNumber\":null,\"preplannedDate\":null,\"workOrderStatus\":7,\"shortageIndicator\":true,\"customerWaiting\":false,\"vehicleDescriptionShort\":\"Volvo V40 Cross Country\",\"vehicleModelYear\":2018,\"colorDescription\":\"Blå\",\"fuelDescription\":\"Diesel\",\"email\":null,\"customer\":{\"customerNumber\":null,\"name\":\"Volvo Bil I Göteborg AB\",\"telephone\":null,\"email\":null,\"customerType\":1},\"mainPayerCustomerType\":1,\"notes\":null,\"vehicleIdentificationNumber\":\"YV1MZ79L0J2139968\"}],\"webWorkOrders\":[]}}"
当在postman中收到相同的响应时,无法将其解析为json,因为它被切断,并且在计划文本中看起来像:

{"errorCode":0,"errorData":null,"data":{"previousWorkingDayWorkOrders":[],"nextWorkingDayWorkOrders":[],"todaysWorkOrders":[{"workOrderId":1229253.0,"employeeNumber":5000000037.0,"employeeName":"VERKADM, VERKADM","vehicleRegistrationNumber":"PXG948","dealerOrderNumber":null,"bookingNumber":"349","preplannedDate":"2020-02-06T07:00:00","workOrderStatus":5,"shortageIndicator":true,"customerWaiting":false,"vehicleDescriptionShort":"Volvo V40 Cross Country","vehicleModelYear":2018,"colorDescription":"Blå","fuelDescription":"Diesel","email":null,"customer":{"customerNumber":null,"name":"Volvo Bil I Göteborg AB","telephone":null,"email":null,"customerType":1},"mainPayerCustomerType":1,"notes":null,"vehicleIdentificationNumber":"YV1MZ79L0J2139968"}],"nonInvoicedWorkOrders":[{"workOrderId":1232753.0,"employeeNumber":5000000037.0,"employeeName":"VERKADM, VERKADM","vehicleRegistrationNumber":"PXG948","dealerOrderNumber":null,"bookingNumber":null,"preplannedDate":null,"workOrderStatus":7,"shortageIndicator":true,"customerWaiting":false,"vehicleDescriptionShort":"Volvo V40 Cross Country","vehicleModelYear":2018,"colorDescription":"Blå","fuelDescription":"Diesel","email":null,"customer":{"customerNumber":null,"name":"Volvo Bil I Göteborg AB","telephone":null,"email":null,"customerType":1},"mainPayerCustomerType":1,"notes":null,"vehicleIdentificationNumber":"Y
你知道为什么这不起作用吗

编辑:我还应该指出,通过删除中间件
app.UseApiResultMiddleware()
一切都很好,但我们仍希望总结我们的回答

编辑2。多亏了dbc的回应,我成功地解决了这个问题。通过将响应内容的长度设置为缓冲区的长度,它可以完美地工作

context.Response.ContentLength = buffer.Length;

让我困惑的是,当我们使用.Net core 2.2时,没有使用System.Text.Json设置长度,而是使用了您添加的NewtonsoftJson

services.AddControllers().AddNewtonsoftJson()

但我不确定Middleware是否能够访问它(以前从未尝试过这种服务注册方法)

您是否尝试使用旧版本添加它


services.AddMvc().AddNewtonsoftJson()

其他可能性,您没有遵循.NET Core 3.0


使用软件包而不是软件包。

我收到了同样的问题。但在中间件服务中添加了以下行之后,我获得了成功

 string plainBodyText = await new StreamReader(context.response.Body).ReadToEndAsync();    
context.Response.ContentLength = plainBodyText.Length;

欢迎您是否尝试刷新响应流?谢谢。我已经尝试过刷新它,但这似乎不是问题所在。只是简单说明一下,您知道
{}
作为json无效吗?您的json无效。对不起,我发布的json实际上是实际json的解析值,它是在代码中的测试变量中解析的匿名对象的解析值。我用序列化的jsonI更新了post,实际上在迁移时替换了它。自3.0以来,有了添加MvC场景的新选项。您可以在这里找到更多信息:是的,我们确实遵循了迁移指南,并且使用了Microsoft.AspNetCore.Mvc.NewtonsoftJson。如果我删除行:app.UseApiResultMiddleware();,则对象的解析工作正常;。但是,这些响应并没有包含在ApiResultResponse类中
 string plainBodyText = await new StreamReader(context.response.Body).ReadToEndAsync();    
context.Response.ContentLength = plainBodyText.Length;