I am working on a small and self-contained poll application, not unlike Straw Poll whereby one user can submit a poll and other users can vote (but only once).
I am building this little application in the open, using Angular for the front-end and Web Api for the back-end. I am using Fluent Validation to validate incoming models.
Using an action filter and Fluent Validation I have managed to remove all basic model validation from my controller.
I need to carry out some more advanced validation after I load the poll from the database. My action method has become overrun by such validation logic as you can see:
public IHttpActionResult Put(int pollId, VoteInput voteInput)
{
var poll = _session.Load<Poll>(pollId);
var voterIp = Request.GetOwinContext().Request.RemoteIpAddress;
if (poll == null)
{
return BadRequest("you cannot vote on a poll that does not exist.");
}
if (poll.VoterIps.Contains(voterIp))
{
return BadRequest("you cannot vote on this poll because you have already voted.");
}
if (voteInput.Options.Length > 1 && !poll.MultiChoice)
{
return BadRequest("you cannot vote for more than one option. noob.");
}
foreach (var option in poll.Options.Where(option => voteInput.Options.Contains(option.Id)))
{
option.Votes += 1;
}
poll.VoterIps.Add(voterIp);
_session.SaveChanges();
return Ok();
}
I would very much like to remove some, if not all of this validation logic from the controller.
I have a really sound infrastructure - I am using Fluent Validation and a DI Framework - but owing to my inexperience with said technologies, I cannot think of a clean way to extract the validation logic.
What are some ways I can reduce or eliminate the validation in my controller?