Reputation: 149
Does anybody have any links or advice on how to hook up validation that requires interacting with the database before updating or adding to the database? Every example I see shows how to validate properties e.g. "Is Required", "Is Email", "Is Numeric", etc, but how do you hook up validation for "Can't order out of stock item"? This xVal blog post touches on it but doesn't provide an example.
I've been following the NerdDinner tutorial which uses a Repository, but this is the bit I don't quite get... Say we had an OrderController with a Create method, and before creating an order we had to first check that the item is in stock. In the NerdDinner style the Controller uses the Repository to talk to the database, so how would our Order object (Model) be able to enforce this validation along with the property validation, as it can't talk to the database?
Thanks for any help
Upvotes: 7
Views: 2336
Reputation: 624
In the NerdDinner tutorial, you can checkout the IsVaild and then the GetRuleViolation methods. Based on your business and database rules, you could use these to check the data you have before you insert it. You could even create an IsValidForInsert Method to check any insert specific rules you need to enforce.
In NerdDinner, the GetRuleViolation allows you to retrieve the violated rules and bubble them up to the interface as you choose.
public bool IsValid
{
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations()
{
if (CheckDbForViolation)
yield return new RuleViolation("Database Violation", "SomeField");
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title is required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description is required", "Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy is required", "HostedBy");
... etc ...
yield break;
}
public bool CheckDbForViolation()
{
/// Do your database work here...
}
You could take this further and split database code into the repository. The CheckDbForViolation would call the repo for the info and then determine if there was a violation or not. In fact if you are using a repository, I think that would be the preferable way of doing it.
Upvotes: 3
Reputation: 30945
You do not really need any guidance from examples on how to do this. Ultimately you will have to be able to create such applications on your own which means being creative.
I've decided from the beginning do not use either built-in validation or membership API in order not to run into its limitations at some point of time.
For your situation: it's pretty much standard.
Imagine the execution flow as follows:
Try to keep controller methods as empty as possible. The validation and operation logic should reside in your models and business logic. The controller should basically attempt the one intended operation and based on the status returned just return one view or the other. Maybe a few more options, but not the whole load of checks for user roles, access rights, calling some web services etc. Keep it simple.
P.S. I sometimes get the impression that the built-in features intended to simplify simple things for majority of developers tend to create new barriers over the removed ones.
Upvotes: 1
Reputation: 2852
I would create an OrderService with a method PlaceOrder(Order order). The OrderService use the Repository to perform CRUD ops and to enforce business rules (stock check) and eventually thrown exception on rules violation you can catch and report to the user.
Upvotes: 0