2

I'm working on an ASP.NET 2.2 Web API project which uses a wrapper for producing consistent responses. After some searching, I found that the team followed the implementation from the article, “A Custom Wrapper For Managing Exceptions And Consistent Responses”.

This works as expected. Now we are planning to upgrade to ASP.NET Core 3.1. After upgrading, this doesn't work as expected. I think it was due to breaking changes between ASP.NET Core 2.2 and 3.1. I fixed all these following Microsoft’s Migrate from ASP.NET Core 2.2 to 3.0 guide.

Now my JSON response from the API breaks.

Here is the code that gets executed when the response is successful:

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);  
}  

I debugged until it hit the return context.Response.WriteAsync(jsonString); inside the HandleSuccessRequestAsync() method. Everything is fine. But the JSON response breaks.

Expected Response:

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

Actual Response:

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

Please assist me on where I'm going wrong? Is this because of theASP.NET Core 3.1 upgrade?

5
  • Did you mean that Result in json has no data? According to your provided link and the migration document , my 3.1 project which is migrated from 2.2 project worked well ,and the Result has the value.If you want the community review and debug the code ,could you share a complete demo that can reproduce the issue ? Commented Mar 12, 2020 at 11:01
  • I'm getting the response data but it is truncated..Here is the my repo link containing demo with above code APIResponseWrapper. Please assist. Commented Mar 12, 2020 at 13:51
  • When you say, “Everything is fine. But the JSON response breaks.” do you mean that the object is getting deserialized into JSON correctly—but then getting truncated at some point between the return and the user? Or do you mean that everything works fine, except that the deserialization is returning the truncated JSON? Commented Apr 5, 2020 at 7:44
  • Did you ever find a solution to this issue? Can you please share? Commented Jul 13, 2020 at 16:27
  • @M Akin you're using response wrapper? What's your issue? Commented Jul 13, 2020 at 19:10

1 Answer 1

7

We were having this same problem in an application where we use custom middleware to change the response body. This page was helpful:

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

We didn't have to create a wrapper like in the above page for the HttpResponse.Body as long as we changed the ContentLength to null before writing our altered body to the Response. It was helpful though to learn what while ASP.NET Core 2.2 does not set ContentLength when the controller action returns its value and the response body is written, ASP.NET Core 3.1 does set the ContentLength. As a result, when we altered the response body, the content became longer than the set ContentLength.

We have code that replaces the response body with a memory string before the controller action is awaited. This is to be able to capture the response from any controller method. Then the response was altered and the original stream restored to the response object. Then the altered response was written to the body with its original stream in place.

What was happening was that when the middleware awaited the controller response, the response set the ContentLength. Then, when we wrote the altered response body, that ContentLength was not updated. So the received json string was truncated. We were able to change ContentLength to the length of the altered content (or use null, both worked), IF we change the length before writing the altered body to the response.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for sharing your learning. It helped me and it worked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.