2

Good day

I am new to API's. I have consumed them, but never had to published my own until now.

I would like to have uniformity in all error responses. I would like to have all my responses (other than 200 range) look the same as the default error response, but when I add my own error, then only my error is returned in Postman.

Illustration:

When a required parameter is not passed for example, there is an auto default response body which look like this:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-118adfb731bbdb32e865873f70487da2-f5994dea1e69866a-00",
    "errors": {
        "Spec": [
            "The Spec field is required."
        ]
    }
}

Note that I am not validating fields and I did not generate the above error message.

When I return a BadRequest() response, in Postman I see a response body also containing the type, status, title and traceId:

API:

public async Task<ActionResult> GetList([FromQuery] SearchCriteria criteria)
{ 
    return BadRequest();  
}

Response:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "Bad Request",
    "status": 400,
    "traceId": 
}

BUT when I add an error message, then only my error message is returned in Postman:

API:

public async Task<ActionResult> GetList([FromQuery] SearchCriteria criteria)
{ 
    return BadRequest(error: new { error = "Unable to return list" });  
}

Response:

{
    "error": "Unable to return list"
}

How can I add my own error message and also still have the type, title, status, and traceId in the response so the user always knows what to expect?

Thank you in advance.

CSharpDev
  • 43
  • 3
  • 1
    https://stackoverflow.com/questions/61247934/add-a-message-to-your-http-400-bad-request-in-asp-net-core-3-1 – CodeCaster Apr 13 '23 at 16:13

2 Answers2

2

Probably easiest approach would be using ValidationProblem:

ModelState.AddModelError("return", "Unable to return List");
return ValidationProblem(ModelState);

Which produces the following response for me:

{
   "type":"https://tools.ietf.org/html/rfc7231#section-6.5.1",
   "title":"One or more validation errors occurred.",
   "status":400,
   "traceId":"00-4091c0b6419e8cc5d4e9cb1da3764f11-d2bc593ce1a51e0a-00",
   "errors":{
      "return":[
         "Unable to return List"
      ]
   }
}

Otherwise you might need to dabble with methods exposed by ProblemDetailsFactory.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    Thank you, this is what I was looking for. Just a pity that the title will always be "One or more validation errors occurred." when I would also want to use this response body for something like a SQL timeout. But I will also fiddle with the ProblemDetailsFactory as you suggested. – CSharpDev Apr 14 '23 at 14:31
0

You should return a JsonResult with a custom class

JsonResult has a StatusCode property you can set

// model to return to client side
private class ReturnModel
{
    public string? message { get; set; }
    ...
}

// in controller method
return new JsonResult(new ReturnModel
{
    message = "..."
})
{
    StatusCode = (int)HttpStatusCode.BadRequest
}; 
Codingwiz
  • 192
  • 2
  • 14
  • 2
    No, the whole point of "problem JSON" is that it's a standardized way of returning error responses and that you don't have to build your own response models. – CodeCaster Apr 13 '23 at 16:02
  • @CodeCaster well since you know an alternative solution, why don't you post it ? – Codingwiz Apr 13 '23 at 16:07
  • Because I'm on mobile and can't find a duplicate that quickly. – CodeCaster Apr 13 '23 at 16:11
  • 1
    @Codingwiz Thank you. I actually thought about creating my own body that mimics the default response body. But it seems I will be able to use the ProblemDetailsFactory to achieve the expected result. – CSharpDev Apr 14 '23 at 14:36