atwrok8
atwrok8

Reputation: 149

asp.net mvc database interaction validation

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

Answers (3)

Mitch Baker
Mitch Baker

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

User
User

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:

  1. Post form
  2. Validate input data format without talking to the database
  3. If (2) is pass, then you validate the input from the point of business rules/data integrity. Here you talk to the database
  4. If (3) passed then perform your operation whatever it is. If it somehow fails (maybe data integrity rules in the database prohibit the operation, say, you deleted a related object from the other browser window) then cancel it and notify the user of an operation error.

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

Andrea Balducci
Andrea Balducci

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

Related Questions