I have certain panels on my page that are hidden under certain circumstances.
For instance I might have a 'billing address' and 'shipping address' and I dont want to validate 'shipping address' if a 'ShippingSameAsBilling' checkbox is checked.
I am trying to use the new DataAnnotations capabilities of ASP.NET MVC 2 (preview 1) to achieve this.
I need to prevent validation of the 'shipping address' when it is not displayed and need to find the way way to achieve this. I am talking mainly server side as opposed to by using jquery.
How can I achieve this? I have had several ideas, related to custom model binding but my current best solution is below. Any feedback on this method?
For the CheckoutModel I am using this approach (most fields hidden):
The custom model binder removes all ModelState errors for fields beginning with 'ShippingAddress' if it finds any. Then 'TryUpdateModel()' will return true.
Any better solutions?
For the more complex cases I moved away from simple DataAnnotations to the following: Validation with visitors and extension methods.
If you want to make use of your DataAnnotations you would replace something like the following:
with a method to validate a property by name via DataAnnotations (which I don't have atm).
http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html
This isn't related to DataAnnotations but have you looked at the Fluent Validation project? It gives you fine grain control over your validation and if you have object-to-object validation an aggregate object of the two objects will get you going.
Also it seems to have been build with MVC in mind but it also has its own "runtime" so that you can use it in other .NET applications as well which is another bonus in my book.
Make sure the fields you don't want validated are not posted to the action. We only validate the fields that were actually posted.
Edit: (by questioner)
This behavior has changed in MVC2 RC2 :
I can see your predicament. I'm looking for other validation solutions also with regard to complex validation rules that might apply to more than one property on a given model object or even many properties from different model objects in a object graph (if your unlucky enough to be validating linked objects like this).
The limitation of the
IDataErrorInfo
interface is that a model object satisfies the valid state simply when none of the properties have errors. This is to say that a valid object is one where all of it's properties are also valid. However, i may have a situation where if property A, B and C are valid - then the whole object is valid.. but also if property A is not valid but B and C are, then the object satisfies validity. I simply have no way of describing this condition/rule with theIDataErrorInfo
interface /DataAnnotations
attributes.So i found this delegate approach. Now many of the helpful advancements in MVC didn't exist at the time of writing this article but the core concept should help you. Rather than using attributes to define the validation conditions of an object we create delegate functions that validate more complex requirements and because they're delegated we can re-use them. Sure it's more work, but the use of delegates means that we should be able to write validation rule code once and store all the validation rules in the one place (maybe service layer) and (the kool bit) even use the MVC 2
DefaultModelBinder
to invoke the validation automatically (without heaps of checking in our controller actions - like Scott's blog says we can do withDataAnnotations
. Refer to the last paragraph before the 'Strongly Typed UI Helpers' heading)!I'm sure you can beef the approach suggested in the above article up a little with anonymous delegates like
Func<T>
orPredicate<T>
and writing custom code blocks for the validation rules will enable cross-property conditions (for example the condition you referred to where if yourShippingSameAsBilling
property is true then you can ignore more rules for the shipping address, etc).DataAnnotations
serves to make simple validation rules on objects really easy with very little code. But as your requirements develop you will need to validate on more complex rules. The new virtual methods in the MVC2 model binder should continue to provide us with ways of integrating our future validation inventions into the MVC framework.