Home > Software engineering >  Return Generic response object/json for all the controllers methods using .NetCore middleware
Return Generic response object/json for all the controllers methods using .NetCore middleware

Time:07-29

My controller:

public class MyController : ControllerBase
{
  [HttpGet("/getResponse/{userId}")]
  public async Task<MyResponse> GetResponseAsync(long userId)
  {
     return await _myService.GetResponseAsync(userId);
  }
  [HttpGet("/getUser/{userId}")]
  public async Task<MyUser> GetUserAsync(long userId)
  {
     return await _myService.GetUserAsync(userId);
  }
}

though my controller returns an object of MyResponse or MyUser class, I want to return a custom generic response object i.e.

public class ApiResponse
{
  public object Response { get; set; }
  public bool IsSuccess { get; set; }
  public IList<string> Errors { get; set; }
  public ApiResponse(object response, bool success, IList<string> errors = null)
  {
     this.Response = response;
     this.IsSuccess = success;
     this.Errors = errors;
  }
    
  public ApiResponse()
  {
  }
}

I tried to use IActionFilter's OnActionExecuted(ActionExecutedContext context) to read the response object, but I don't see any response of MyUser or MyResponse object in the body when i debug for variable a.

public void OnActionExecuted(ActionExecutedContext context)
        {
            ApiResponse _response = new ApiResponse();
            var httpResponse = context.HttpContext.Response;
            if (httpResponse != null)
            {
                if (httpResponse.StatusCode == 200)
                {
                   var a = httpResponse.Body;
                }
            }
        }

Is there a way to read the type of object and assign that particular object to the ApiResponse.response proeperty?

CodePudding user response:

There are a few types of MVC filters, and IActionFilter is not the best tool for this job. What you want is ResultFilter.

Please take a look at official documentation here https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0 for more details.

An answer provided here may also be useful for you: https://stackoverflow.com/a/64725441/2895299

However, it is going to work with your filter implementation as well, you're just looking for a response object in wrong place. Your object is going to be accessible under:

context.Result

Response in HttpContext object is going to be accessible later, not at filter stage of MVC pipeline. Please observe, that context.HttpContext.Response.HasStarted is equal to false.

CodePudding user response:

There's already IETF RFC 7807 for HTTP API problem responses, with its own content type, application/problem json. ASP.NET Core uses it to return automatic model validation failure responses.

It's a bad idea to use a custom format when there's a standard that's actually used by clients and libraries.

Example responses can be :

   HTTP/1.1 403 Forbidden
   Content-Type: application/problem json
   Content-Language: en

   {
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345",
                 "/account/67890"]
   }

Or

   HTTP/1.1 400 Bad Request
   Content-Type: application/problem json
   Content-Language: en

   {
   "type": "https://example.net/validation-error",
   "title": "Your request parameters didn't validate.",
   "invalid-params": [ {
                         "name": "age",
                         "reason": "must be a positive integer"
                       },
                       {
                         "name": "color",
                         "reason": "must be 'green', 'red' or 'blue'"}
                     ]
   }

ASP.NET Core uses the ProblemDetails and the more specific ValidationProblemDetails classes to report errors.

It's possible to send a Problem or ValidationProblem response using the Problem or ValidationProblem functions, eg:

var details=new ValidationProblemDetails(someDictionary);
return ValidationProblem(details);

The Handle errors in ASP.NET Core web APIs article shows how ASP.NET Core can be configured to returns customized ProblemDetails for specific exceptions

  • Related