views:

440

answers:

2

I'm trying to figure out the best way to validate data within a MVC C# app and xVal seemed to be the best fit. However I'm running into a problem with data type validation.

At first I was doing an UpdateModel into the DTO and then running the validation on the DTO. This worked great for things like required fields, however UpdateModel would throw an exception if you tried, for example, to map a string ("asd") into a decimal field. Since UpdateModel had to be ran before there was any data to validate I wasn't sure how to get around that.

My solution was to create a DTO per form that UpdateModel would copy into, run validation on that, and then copy values out into the proper DTOs. All the attributes on the form DTO would be strings so UpdateModel never bombs out, and I'd enforce the data validation through xVal. However while rules like required are kicking in, I can't seem to get the DataType rule to kick in (in this case trying DataType.Currency).

I had also tried getting the client-side validation to work, but I was hoping there was a clean way to do server-side validation of data types.

What have others done with regards to validating data types on the server-side?

+1  A: 

I'm using custom validators derived from ValidationAttribute for validating data that should be parsed on the server-side from string to other data types. For example:

public class DateAttribute : ValidationAttribute
    {

        public override bool IsValid(object value)
        {
            var date = (string)value;
            DateTime result;
            return DateTime.TryParse(date, out result);
        }
    }

I've also found a way to turn such validation attributes into client-side AND server-side validation attributes without writing any custom javascript code. I just have to derive from a different validation attribute base class. Have a look at my blog article about client-side validation if you'd like to learn more about this.

Adrian Grigore
The validation isn't the issue, it's where to store it before it is validated. I ideally wanted it to copy to a DTO without the need for a viewmodel -- ex a currency field would go into a decimal, etc. However this breaks once you try to enter a string into an int field and you use UpdateModel to copy the fields form the form into the viewmodel or DTO.
Parrots
+2  A: 

What I ended up doing was creating some DTOs that represent the forms. These DTOs would take a Request.Form in and automatically map all the form values into the internal properties (ex public string email, public string firstname) based on them being the same name as the form values.

They would have all string properties and I'd put the xVal attributes on them. I'd then use xVal and regular expressions to make sure the data coming in was valid (ex a valid date, email, number, etc). This way there would never be an exception thrown because it was always going into a string, as opposed to .Net trying to parse it into a date or something.

This would make sure that the data always made it to xVal where I could run the validation I want, and then convert it to the proper type like DateTime once I know I have valid data.

Parrots