Reputation: 24676
I'm wondering if there is a way in API Controllers to return a custom object as response body for methods like: BadRequest()
or NotFound()
.
For example, for 404 error, I'd like to return something like:
{
"StatusCode": 404,
"Error": "Not Found",
"Message": "Custom message..."
}
Instead I'm getting this:
{
"Message": "Custom message..."
}
At the moment to return complex response body I'm using Ok()
this way:
return Ok(new
{
Success = false,
Message = "Custom message...",
// other fields...
});
But obviously I'm returning a 200 status that is not so meaningful.
Is there a better way to achieve this?
Upvotes: 1
Views: 3261
Reputation: 873
Thanks for your code, it worked (after a while). It seems that you have written pseudo-code rather than code itself. So, in order to make life easier to other, here is your same exact code but withing a class which runs.
public sealed class JsonErrorResult : JsonResult {
private readonly HttpStatusCode _statusCode;
public JsonErrorResult(HttpStatusCode sCode, object value) : base(value) {
_statusCode = sCode;
}
public override Task ExecuteResultAsync(ActionContext context) {
context.HttpContext.Response.StatusCode = (int)_statusCode;
return base.ExecuteResultAsync(context);
}
public static JsonResult JsonError(HttpStatusCode statusCode,
string message, string error = "") {
var result = new JsonResult(new {
StatusCode = Convert.ToString((int)statusCode),
Error = error,
Message = message
});
result.StatusCode = (int)statusCode;
return result;
}
}
and finally you call it like so:
return JsonErrorResult.JsonError(System.Net.HttpStatusCode.Unauthorized,
"error msg");
Upvotes: 0
Reputation: 67080
If you need a quick solution just jump to Short Way, read this just to understand how it works under the hood. Derive your own JsonErrorResult
class derived from JsonResult
:
public sealed JsonErrorResult : JsonResult
{
public JsonErrorResult(StatusCodes statusCode, object value)
: base(value)
{
_statusCode = statusCode;
}
private readonly JsonErrorResult StatusCodes _statusCode;
}
Now override ExecuteResultAsync()
method to change status code of default JsonResult
implementation:
public override Task ExecuteResultAsync(ActionContext context)
{
context.HttpContext.Response.StatusCode = _statusCode;
return base.ExecuteResultAsync(context);
}
You simply return calling BadRequest()
you simply do this:
return new JsonErrorResult(StatusCodes.Status400BadRequest, new
{
StatusCode = "404",
Error = "bla bla bla",
Message = "bla bla bla"
});
Of course if you use it often you may want to create your own helper method:
protected static JSonErrorResult JsonError(StatusCodes statusCode,
string error, string message)
{
return new JsonErrorResult(statusCode, new
{
StatusCode = Convert.ToString((int)statusCode),
Error = error,
Message = message
});
}
Used like this:
return JsonError(StatusCodes.Status400BadRequest, "bla bla bla", "bla bla bla");
JsonResult
already has StatusCode
property then your helper method may become like this:
protected static JSonResult JsonError(StatusCodes statusCode,
string error, string message)
{
var result = new JsonResult(new
{
StatusCode = Convert.ToString((int)statusCode),
Error = error,
Message = message
});
result.StatusCode = (int)statusCode;
return result;
}
Upvotes: 4
Reputation: 4142
I usually return something like this:
return Json(new { success = false, data = "" }, JsonRequestBehavior.AllowGet);
And then in my AJAX success, I do:
if(result.success){
result.data...
}else{
//error...
}
If you do not want to always send a 200 code, then can you do something like this?
//if success...
Response.StatusCode = 200;
return Json(new { responseCode = 200, data = "", message = "..." }, JsonRequestBehavior.AllowGet);
//if failure...
Response.StatusCode = 404;
return Json(new { responseCode = 404, data = "", message = "..." }, JsonRequestBehavior.AllowGet);
Upvotes: 0
Reputation: 22323
Create function to deal with error.
function AjaxCompletion(xhr) {
switch (xhr.status) {
case 200:
//Your Message
break;
case 401: //unauthorize
//Your desire message
break;
}
}
And in AJAX complete
:
complete: function (xhr) {
AjaxCompletion(xhr);
}
Upvotes: 0