Before WebAPI, I did all client-side remote validation calls using regular MVC action methods. With WebAPI, I can now have POST, PUT, DELETE, and GET methods on an ApiController. However, validation still needs to happen.
I have successfully been able to put remote validation action methods on an ApiController and get them to work. Before submitting a POST, PUT, or DELETE for a resource, the client can POST to one or more validation URL's to validate user input and receive appropriate validation messages.
My question is, should these remote validation actions be on an ApiController? Or a regular MVC controller? It seems to me having them all in the ApiController makes the most sense, because that class can then encapsulate everything having to do with resource (and resource collection) mutations.
Update: reply @tugberk
I should elaborate. First, we are not using DataAnnotations validation. There are already rich validation rules and messages configured on the domain layer commands using FluentValidation.NET. Many of the validation classes use dependency injection to call into the database (to validate uniqueness for example). FluentValidation has good pluggability with MVC ModelState, but I have not found a good way to plug it into WebAPI ModelState yet.
Second, we are doing validation at the POST, PUT, and DELETE endpoints. Clients do not need to know the validation endpoints in order to discover what went wrong. Here is an example:
var command = Mapper.Map<CreateCarCommand>(carApiModel);
try
{
_createHandler.Handle(command);
}
catch (ValidationException ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
}
Clients will get a 400 response along with a message indicating what went wrong. Granted, this is not as granular as the response in the example you linked to. Because we are just returning a string, there is no easy way to parse out which fields each validation message belongs to, which is needed for our own HTML + javascript client of the API. This is why I spiked out adding more granular validation endpoints (as a side note, they are consumed by field-specific knockout-validation calls on our javascript client).