views:

212

answers:

3

On the NerdDinner example a set of business rules are written to validate the data on a model. Things like empty strings are checked for and by calling modelObject.GetRuleViolations() you can get them all. But there's another layer of validation which is the database. For example, the datetime field is left for validation to the database, which only accepts a string that can be converted into a DateTime object.

The problem I see is that modelObject.GetRuleViolations() never return the violation for datetime. So even when it is correctly prevented from saving the record and the form is shown back specifying there's an error and highlighting the datetime field, there's no specific error message. Is there a way to get the database validation errors among the business rules validation errors?

+1  A: 

You need to catch the exceptions thrown by your Data Access Layer, and convert those into calls which update the ModelState to indicate the errors in question. There's not really a good way to do this on a global level, since specific SQL errors will only be able to be interpreted at the time they're called, rather that handled in a generic way.

Brad Wilson
A: 

I don't remember the exact code from NerdDinner, though I have looked at it. However, in my applications, I typically do a raiserror('Some error',16,1) in the database and use a try/catch in my controller / model like so:

public void DoSomething() 
{
    try
    {
        // Some database activity
    } 
    catch (SqlException ex) 
    {
        ViewData["ErrorMessage"] = ex.Message;
    }
}

I can then render the error in my view however I want.

Chris
In general, I would be very careful about so blindly putting exception status messages into the page for end users to see, because you could be inadvertantly giving about very sensitive information about the shape of your database.
Brad Wilson
A: 

Your assumption is wrong. The datetime field is not left for validation on the database.

One thing I had to grok in the NerdDinner/MVC lessons was that validation will occur in both the Dinner.cs OnValidate() partial method and in the DinnersController.cs in the call to UpdateModel(). This call copies the text from the screen into the Model. If, for example, it tries to copy text to a float, or parse and invalid date, it will update the ModelState and throw an error. The normal validation will not run.

Ken H