Click here to Skip to main content
15,846,726 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
1


Hi I want to create middleware for Asp.net core to wrap http response that returns response like below

{

{
"count":1,"timestamp":"2021-12-18T01:13:41.2985038+05:00",
"status":"Success",
"results":[
{
"mayPrint":null,"mayEdit":null,"mayAddCopy":null,"mayDelete":null,"mayOverride":null
}
]}


What I have tried:

I created middleware but it truncate the response and give error can't parse JSON and also it displays extra slashes in the results array it cut the response as seen below
"cannot parse Json results
"results":"[{\"code\":\"465\",



My code below is
public class ResponseMiddleware
{
    public class ResponseClass
    {
        public int count { get; set; }

        public DateTime timestamp { get; set; }

        public string status { get; set; }

        public object results { get; set; }
        public string ErrorMessage { get; set; }
    }
    private readonly RequestDelegate _next;
    public ResponseMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (IsSwagger(context))
            await this._next(context);
        else
        {
            var existingBody = context.Response.Body;
            using (var newBody = new MemoryStream())
            {
                context.Response.Body = newBody;
                await _next(context);
                var newResponse = await FormatResponse(context.Response);
                context.Response.Body = new MemoryStream();
                newBody.Seek(0, SeekOrigin.Begin);
                context.Response.Body = existingBody;
                var newContent = JsonConvert.DeserializeObject(new StreamReader(newBody).ReadToEnd());

                // Send modified content to the response body.
                //
                await context.Response.WriteAsync(newResponse);
            }
        }
            
    }

    private bool IsSwagger(HttpContext context)
    {
        return context.Request.Path.StartsWithSegments("/swagger");
    }
    private async Task<string> FormatResponse(HttpResponse response)
    {
        //We need to read the response stream from the beginning...and copy it into a string...I'D LIKE TO SEE A BETTER WAY TO DO THIS
        //
        response.Body.Seek(0, SeekOrigin.Begin);
        var content = await new StreamReader(response.Body).ReadToEndAsync();
        var Response = new ResponseClass(); 
        Response.status = response.StatusCode==200? "success": "Error";
        if (!IsResponseValid(response))
        {
            Response.ErrorMessage = content;
        }
        else
        {
            Response.results = content;
        }
        Response.count = response.ToString().Length;
        var json = JsonConvert.SerializeObject(Response);

        //We need to reset the reader for the response so that the client an read it
        response.Body.Seek(0, SeekOrigin.Begin);
        return $"{json}";
    }

    private bool IsResponseValid(HttpResponse response)
    {
        if ((response != null)
            && (response.StatusCode == 200
            || response.StatusCode == 201
            || response.StatusCode == 202))
        {
            return true;
        }
        return false;
    }
}
Posted
Updated 11-Dec-22 5:17am
Comments
Richard MacCutchan 21-Dec-21 8:51am    
The results field in your JSON data is an array, but in your code it is a single object.
AzeeM_R 21-Dec-21 14:40pm    
Richard can you tell me where to fix it ? I am unable to resolve thanks
Richard MacCutchan 22-Dec-21 4:01am    
You need to change the declaration of the results object to an array, thus:
public object results[] { get; set; }
AzeeM_R 27-Dec-21 14:15pm    
HI Richard
Now the response truncate at the end Can you look into this link please
https://www.codeproject.com/Questions/5320578/Api-response-truncate-at-the-end

1 solution

To create a custom HTTP response in ASP.NET Core, you can use the ObjectResult class. The ObjectResult class allows you to return a custom object as the response from a controller action.

Here's an example of how you might use the ObjectResult class to return your custom response:

public class MyController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        // Create a custom response object
        var response = new
        {
            count = 1,
            timestamp = DateTime.UtcNow,
            status = "Success",
            results = new[]
            {
                new
                {
                    mayPrint = (bool?)null,
                    mayEdit = (bool?)null,
                    mayAddCopy = (bool?)null,
                    mayDelete = (bool?)null,
                    mayOverride = (bool?)null
                }
            }
        };

        // Return the custom response using the ObjectResult class
        return new ObjectResult(response);
    }
}


This will return a custom HTTP response with the following format:

{
  "count": 1,
  "timestamp": "2021-12-18T01:13:41.2985038+05:00",
  "status": "Success",
  "results": [
    {
      "mayPrint": null,
      "mayEdit": null,
      "mayAddCopy": null,
      "mayDelete": null,
      "mayOverride": null
    }
  ]
}


You can then use this custom response in your ASP.NET Core web API as needed. Keep in mind that this is just an example, and you may need to adjust the code to fit your specific needs.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900