Answered by:
Web API Controller How to test for error and return them correctly

Question
-
User-1274246664 posted
The following is an example of a web api controller as the current example stands I and wondering what the best practices should be to do the following handle errors of bad data that is passed in and returning notification back to the requester? Looking at best practice are there other noticeable omissions that would be helpful in following best practices?
[Route("api/Animals")] public class AnimalController : Controller { const string DBConnectionString = "data source=(local);integrated security=true"; public AnimalController() { } [HttpPost] public IActionResult GetAnimalByName([FromBody]string param) { var db = new DbConnection(DBConnectionString); List<Animal> animalList = db.Animal.Where(e => e.AnimalName.Contains(param)).ToList(); return Ok(animalList); } [HttpPost] public IActionResult PostNewAnimal([FromBody]Animal newAnimal) { if (newAnimal == null || newAnimal.AnimalName == null) { return BadRequest("New animal model must be supplied"); } var db = new DbConnection(DBConnectionString); bool duplicateFound = db.Animal.Where(e => e.AnimalName == newAnimal.AnimalName).Any(); if(duplicateFound) { return BadRequest("Animal name already exist"); } else { db.Animal.Add(newAnimal); } return Ok(); } }
Sunday, July 8, 2018 6:56 AM
Answers
-
User-369506445 posted
Hi
You can use validation.
Validation is a very crucial part of Web API implementation
Please refer to belew link
https://www.c-sharpcorner.com/article/learn-about-web-api-validation/
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Sunday, July 8, 2018 6:41 PM
All replies
-
Sunday, July 8, 2018 7:46 AM
-
User-369506445 posted
Hi
You can use validation.
Validation is a very crucial part of Web API implementation
Please refer to belew link
https://www.c-sharpcorner.com/article/learn-about-web-api-validation/
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Sunday, July 8, 2018 6:41 PM -
User-1274246664 posted
Thank you for you answer my question is would the code the way it is structured work now?
Sunday, July 8, 2018 7:16 PM -
User-1171043462 posted
Yes your Code will work. And you can add additional security using the references I gave
Sunday, July 8, 2018 7:23 PM -
User-369506445 posted
Yes.your code is correct . But validation is more flexible
Sunday, July 8, 2018 7:28 PM -
User-1274246664 posted
Thank you very much for your help,
So here is a learning opportunity for me. Looking at the code what do you see that might be a concern and should be addressed?
Sunday, July 8, 2018 7:31 PM -
User-369506445 posted
Things to consider when implementing Web API
- Validate everything
Each and every request should validate before processing it whether an Action method is GET, POST, PUT or DELETE.
- Don't assume about the data you’re receiving
The data should always be assumed to be bad, until it’s been through some kind of validation process.
- Validation as a future-proof quality check
Validated data is more likely to be future-proof for your Web API functionality.
- Clean code is Important.
Validation techniques
The ways given below help you to validate the data for Web API:
1. Model Validation
Model in MVC is basically a representation of our data structure. If you validate this data initially, then everything is good for processing. Web API has Model Binding and Model Validation support. The techniques given below will be used for the validation.
- Data annotation
Is a technique, which can be applied on a model class for an ASP.NET Web API Application to validate the data and handle validation errors. It provides a pretty easy way to enable property-level validation logic within your Model layer. ASP.NET MVC 2 includes support for DataAnnotation attributes. Microsoft published a great article on this.
- IValidatableObject interface
Data annotation enables us to do properly level validation. How about class level validation?
How to do class-level validation methods on model objects for some custom rules? The answer is IValidatableObject interface. IValidatableObject interface to implement custom validation rules on a Product model class. ASP.NET MVC 3 included support for IValidatableObject interface.
Sunday, July 8, 2018 7:40 PM - Validate everything
-
User-369506445 posted
If you’re exposing a Web API, one of the most basic things you should be doing on every request, and especially on those requests that mutate your system’s state, is ensuring that the data you’re accepting is valid. ASP.NET Core MVC (and Web API 2 and MVC 5, too!) supports model validation as part of the model binding process. You’re likely familiar with it and have seen it used in combination with data annotations like [Required] on model types. (Pro Tip: You don’t need [Required] on value types like int and DateTime – these are inherently required as long as their not marked as nullable via int? or DateTime?). Model validation occurs automatically, but it’s up to you to check its IsValid property and act accordingly. If you don’t, you risk working with an invalid model, which can result in bad data or even security vulnerabilities. Assuming you’re writing an API (not returning a View), the most appropriate response when you encounter bad model state is to return a BadRequest with details about why the data wasn’t valid. You can do so like this:
if (!ModelState.IsValid) { return BadRequest(ModelState); }
Unfortunately, this gets pretty verbose when you need to add it to literally every action method in every controller in your API. It violates the DRY principle. You should also strive to avoid conditional logic in your action methods, keeping them small and as simple as possible. In my MSDN article on ASP.NET Core Filters, I talk about how you can use filters to enforce policies in your Web API, making their behavior more consistent and less likely to have bugs. One simple way to do this is with the addition of a ValidateModelAttributethat can be used to perform this same policy action, but using a filter instead of code inside every action method. You’ll find the source for my implementation of this attribute in my Filters sample on GitHub.
If you don’t want to create and maintain your own filter, even one as simple as this one, you can instead just add the Ardalis.ValidateModel nuget package. Once you’ve added it, you can apply it to your API controllers on a per-method or per-class basis. I recommend creating a BaseApiController class that includes the attribute, and having all of your API controllers inherit from this base class. For instance:
[Route("[controller]")] [ValidateModel] public abstract class BaseApiController : Controller { // any other common behavior or properties }
With this in place, you’ll ensure that model validation takes place automatically on every action method in your web API.
Sunday, July 8, 2018 7:44 PM -
User-1274246664 posted
Thank you for all the help it has been very good reading up on so many new ideas. One additional question I was looking at the database connection and though about wrapping it in a using statement for garbage collection and putting a try catch around it.
So it would look like
[HttpPost] public IActionResult PostNewAnimal([FromBody]Animal newAnimal) { if (newAnimal == null || newAnimal.AnimalName == null) { return BadRequest("New animal model must be supplied"); } try()
{
var db = new DbConnection(DBConnectionString); bool duplicateFound = db.Animal.Where(e => e.AnimalName == newAnimal.AnimalName).Any(); if(duplicateFound) { return BadRequest("Animal name already exist"); } else { db.Animal.Add(newAnimal); } return Ok();
}
catch(exception ex)
{
return BadRequest("Data Access error "+ ex.Message");
} }
Would this be better practices that what code was already there?Monday, July 9, 2018 1:20 AM -
User36583972 posted
Hi TinyPond,One additional question I was looking at the database connection and though about wrapping it in a using statement for garbage collection and putting a try catch around it.You can try to use the using Statement and use the try catch to catch the connection opening error.
The C# using statement, SQL, and SqlConnection
https://stackoverflow.com/questions/3079098/the-c-sharp-using-statement-sql-and-sqlconnectionBesides, you can start a new thread if you have a new question. Please don't ask several questions in the same thread.
Best Regards,
Yong Lu
Monday, July 9, 2018 5:56 AM