I am using Default project of .Net Core Web API. In this I have a model validated through data annotations.
For simplicity, I have a basic model with Name required property. In Web API action I want to return custom error message as BadRequest when validation fails but it seems to be returning default format which .Net Core API sends.
Below is error message which .Net Core API is sending.
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|ab22995a-483ab490bf59f517.",
"errors": {
"Name": [
"Name is required"
]
}
}
While I am expecting this
{
"Succeeded": false,
"Message": "One or more validation errors occurred.",
"Errors": {
"Name": [
"Name is required"
]
}
}
My custom response model is
public class APIResponse<T>
{
public bool Succeeded { get; set; }
public T Data { get; set; }
public string Message { get; set; }
public Dictionary<string, List<string>> Errors { get; set; }
}
My custom validation filter looks like
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
APIResponse<bool> apiResponse = new APIResponse<bool>
{
Succeeded = false,
Message = "One or more validation errors occurred.",
Errors = new Dictionary<string, List<string>>()
};
foreach (var modelState in context.ModelState)
{
apiResponse.Errors.Add(modelState.Key, modelState.Value.Errors.Select(a => a.ErrorMessage).ToList());
}
//context.Result = new BadRequestObjectResult(context.ModelState);
context.Result = new BadRequestObjectResult(apiResponse);
}
//base.OnActionExecuting(context);
}
}
And Core API action seems
[Route("[action]")]
[HttpPost]
[ValidateModel]
public async Task<IActionResult> RegisterUser(UserModel model)
{
APIResponse<bool> result = await userAccount.SaveUserAsync(model);
return Ok(result);
}
Please let me know how I can send my own custom response within BadRequest?
I tested your code but can't reproduce your problem, can you offer more information?
If you just want to show three parameters, then you can delete the Data in APIResponse.
My test procedures:
Best Regards,
Jerry Cai
.NET forums are moving to a new home on Microsoft Q&A, we encourage you to go to Microsoft Q&A for .NET for posting new questions and get involved today.
Helping you always. Don't forget to click "Mark as Answer" on the post that helped you.
♠ ASP.NET Core Tutorials → Start from the Beginning and become an Expert in 30 days time ♠
.NET forums are moving to a new home on Microsoft Q&A, we encourage you to go to Microsoft Q&A for .NET for posting new questions and get involved today.
[HttpPost]
public async Task<IActionResult> Login(UserCredentials userCredentials)
{
string passwordHash = "";
SecurityService securityService = new SecurityService();
ClientTicket clientTicket = new ClientTicket();
if (ModelState.IsValid == false)
{
return BadRequest(ModelState);
}
else
{
//Get the user id and password date
await _dataService.GetUserCredentials(userCredentials);
if (userCredentials.UserId == 0)
{ return Problem(statusCode: 400, title: "Invalid user name");
}
//Create the password hash from the password date
passwordHash = securityService.GetPasswordHash(userCredentials);
if (string.IsNullOrEmpty(passwordHash))
{
throw new Exception("SecurityController.Login : Unable to generate password hash");
}
userCredentials.PasswordHash = passwordHash;
//Check if the password is valid
bool isPasswordValid = await _dataService.IsValidPassword(userCredentials);
if (isPasswordValid)
{
//Create the ticket to be returned
clientTicket.Username = userCredentials.Username;
clientTicket.Ticket = securityService.GetTicket();
}
else
{ return Problem(statusCode: 403, title: "Invalid password");
}
}
return Ok(clientTicket);
}
Highlighted in bold. There are some other examples of use on other forums, but the official mention comes
here.
I'm not sure how to consume these using a MVC/Blazor UI, but can help with JS.
The ProblemDetails class is the HTTP standard for handling bespoke errors (read
this) and it essentially returns a simple JSON object that you need to consume with care. Critically the response header status code goes back as 200, so you have to have to enquire into the response body :
//Reload this form, if saved succesfully
if (success) {
window.location.replace(redir); //Using replace means that history is overwritten and new records do not get needlessly recreated
}
}
else {
throw new Error("Login : response body is empty");
}
})
.catch(error => {
window.alert("An error occurred, please see the console for details.");
console.error('Login : ', error)
});
I'm afraid my JS skills are somewhat basic, but hopefully you get the point.
.NET forums are moving to a new home on Microsoft Q&A, we encourage you to go to Microsoft Q&A for .NET for posting new questions and get involved today.
Member
6 Points
64 Posts
How to return custom bad request response in asp.net core API
Oct 19, 2020 07:56 AM|vkagrawal|LINK
Hi,
I am using Default project of .Net Core Web API. In this I have a model validated through data annotations.
For simplicity, I have a basic model with Name required property. In Web API action I want to return custom error message as BadRequest when validation fails but it seems to be returning default format which .Net Core API sends.
Below is error message which .Net Core API is sending.
While I am expecting this
My custom response model is
My custom validation filter looks like
And Core API action seems
Please let me know how I can send my own custom response within BadRequest?
Thanks!!
Participant
940 Points
312 Posts
Re: How to return custom bad request response in asp.net core API
Oct 20, 2020 09:25 AM|Jerry Cai|LINK
Hi,vkagrawal
I tested your code but can't reproduce your problem, can you offer more information?
If you just want to show three parameters, then you can delete the Data in APIResponse.
My test procedures:
Best Regards,
Jerry Cai
Participant
1253 Points
935 Posts
Re: How to return custom bad request response in asp.net core API
Oct 20, 2020 12:21 PM|yogyogi|LINK
Check Returning BadRequest (400), Unauthorized (401), NotFound (404) status codes from Action
♠ ASP.NET Core Tutorials → Start from the Beginning and become an Expert in 30 days time ♠
Member
6 Points
64 Posts
Re: How to return custom bad request response in asp.net core API
Oct 21, 2020 08:06 AM|vkagrawal|LINK
Hi Jerry, are you using .net core 3.1?
Participant
940 Points
312 Posts
Re: How to return custom bad request response in asp.net core API
Oct 21, 2020 08:10 AM|Jerry Cai|LINK
Hi,vkagrawal
Yes, asp.net core 3.1 with web api.
Best Regards,
Jerry Cai
Member
6 Points
64 Posts
Re: How to return custom bad request response in asp.net core API
Oct 21, 2020 08:36 AM|vkagrawal|LINK
That's strange, in my case I am not even able to debug the custom validation filter while testing through postman and I leave some model errors.
Member
7 Points
42 Posts
Re: How to return custom bad request response in asp.net core API
Oct 21, 2020 10:24 AM|PJM8765|LINK
I have used an instance of a "Problem" class:
[HttpPost]
public async Task<IActionResult> Login(UserCredentials userCredentials)
{
string passwordHash = "";
SecurityService securityService = new SecurityService();
ClientTicket clientTicket = new ClientTicket();
if (ModelState.IsValid == false)
{
return BadRequest(ModelState);
}
else
{
//Get the user id and password date
await _dataService.GetUserCredentials(userCredentials);
if (userCredentials.UserId == 0)
{
return Problem(statusCode: 400, title: "Invalid user name");
}
//Create the password hash from the password date
passwordHash = securityService.GetPasswordHash(userCredentials);
if (string.IsNullOrEmpty(passwordHash))
{
throw new Exception("SecurityController.Login : Unable to generate password hash");
}
userCredentials.PasswordHash = passwordHash;
//Check if the password is valid
bool isPasswordValid = await _dataService.IsValidPassword(userCredentials);
if (isPasswordValid)
{
//Create the ticket to be returned
clientTicket.Username = userCredentials.Username;
clientTicket.Ticket = securityService.GetTicket();
}
else
{
return Problem(statusCode: 403, title: "Invalid password");
}
}
return Ok(clientTicket);
}
Highlighted in bold. There are some other examples of use on other forums, but the official mention comes here.
I'm not sure how to consume these using a MVC/Blazor UI, but can help with JS.
The ProblemDetails class is the HTTP standard for handling bespoke errors (read this) and it essentially returns a simple JSON object that you need to consume with care. Critically the response header status code goes back as 200, so you have to have to enquire into the response body :
fetch(postURI, {
mode: 'cors',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
.then(response => response.json())
.then(body => {
if (body != null) {
if (body.status == undefined) {
ticket = body.ticket;
//Save to a cookie
window.sessionStorage.setItem("username",txtName.value);
window.sessionStorage.setItem("ticket", ticket);
//Set redirect address to the home page
if (window.location.port == "") {
redir = window.location.protocol + "//" + window.location.hostname + "/";
}
else {
redir = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/";
}
}
else {
success = false;
throw new Error(body.status + " " + body.title);
}
//Reload this form, if saved succesfully
if (success) {
window.location.replace(redir); //Using replace means that history is overwritten and new records do not get needlessly recreated
}
}
else {
throw new Error("Login : response body is empty");
}
})
.catch(error => {
window.alert("An error occurred, please see the console for details.");
console.error('Login : ', error)
});
I'm afraid my JS skills are somewhat basic, but hopefully you get the point.
Kind regards, Paul
Member
7 Points
42 Posts
Re: How to return custom bad request response in asp.net core API
Oct 21, 2020 10:29 AM|PJM8765|LINK
Hi Jerry,
Apologies for the digression. What tool are you using to grab the screen actions?
Kind regards, paul
Participant
940 Points
312 Posts
Re: How to return custom bad request response in asp.net core API
Oct 22, 2020 01:35 AM|Jerry Cai|LINK
Hi,PJM8765
The tool is 'Screen to gif'.
Best Regards,
Jerry Cai
Member
10 Points
1 Post
Re: How to return custom bad request response in asp.net core API
Jan 03, 2021 05:56 PM|GorgeousPuree|LINK
So what was causing such behavior? I've just copied your code and got the same result.
I've noticed that default validation takes place earlier than custom. That's why default bad request body was returned.
That helped: https://stackoverflow.com/questions/54942192/how-to-customize-error-response-in-web-api-with-net-core
Member
6 Points
64 Posts
Re: How to return custom bad request response in asp.net core API
Jan 13, 2021 07:34 PM|vkagrawal|LINK
Yes, while I was waiting for replies I found that it can be suppressed in startup file and it worked as expected.