Which MVC Validation Framework
I have been evaluating xVal as framework for validating Entities in the ASP.Net MVC Framework. I have recently discovered that开发者_运维问答 each time a validation rule is broken, xVal cause an excpetion to be thrown. To me is seems incorrect. For example, when a user fills in a form, and forgets to fill three required fields , three exceptions will be thrown. Is this good practice? ( Edit: I also read this, so I guess its not good practice)
What are your experiences of using xVal? Is there good alternative validation framework that does not throw exceptions?
Thanks
(PS: I notice that lots of people are reading this, just to let you know I am using Fluent Validation now)
Have you looked at validation in Beta 2?
http://blogs.msdn.com/rickandy/archive/2009/10/03/client-side-validation-for-mvc-2-p2.aspx
No it's not a good practice to show exceptions instead of some simple messages because nothing seriously has been going wrong... You should instead populate ModelState
with these errors and display them on the form using
Html.ValidationMessage("EntityPropertyName");
xVal supports all these. As well as validating on the client side before the form gets posted back.
Some code
When you set DataAnnotations
attributes to your entity classes (or their Metadata companion classes) you will most likely also implement Validate() method. the best way would be to use T4 that will auto generate those for you, so you don't have to repeate the same code over and over...
public IEnumerable<ErrorInfo> Validate()
{
IList<ErrorInfo> errors = DataAnnotationsValidationRunner.GetErrors(this).ToList<ErrorInfo>();
return errors.AsEnumerable();
}
All you have to do then is to call this:
IEnumerable<ErrorInfo> errors = entityObjectInstance.Validate();
if (errors.Any())
{
new RulesException(errors).AddModelStateErrors(filterContext.Controller.ViewData.ModelState, entityPropertyName);
}
And to automate this even further, you can implement this in an action filter, so validation will be automatic for your entity objects that get passed into controller action. Controller actions would only need to check whether ModelState.IsValid()
then.
One more class you'll need here is (and is taken from the web somewhere):
public static class DataAnnotationsValidationRunner
{
public static IEnumerable<ErrorInfo> GetErrors(object instance)
{
var metadataAttribute = instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();
var metaClass = metadataAttribute != null ? metadataAttribute.MetadataClassType : instance.GetType();
var metaClassProperties = TypeDescriptor.GetProperties(metaClass).Cast<PropertyDescriptor>();
var modelClassProperties = TypeDescriptor.GetProperties(instance.GetType()).Cast<PropertyDescriptor>();
return from metaProp in metaClassProperties
join modelProp in modelClassProperties on metaProp.Name equals modelProp.Name
from attribute in metaProp.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(modelProp.GetValue(instance))
select new ErrorInfo(metaProp.Name, attribute.FormatErrorMessage(string.Empty), instance);
}
}
MVC 2
Validation in Asp.net MVC 2 Beta 2 is similar to what xVal does. So if you're not too far into the project and you can consider using code in development progress as your foundation, maybe that is the way to go for you.
I think xVal is great, I've been using it with Castle Validators and it works perfectly. Just catch the RulesException whenever you're running validation and add the errors to your ModelState, e.g.
try
{
// execute validation runner
}
catch (RulesException ex)
{
ex.AddModelStateErrors(ModelState, "prefix");
}
ASP.NET MVC v2 will introduce its own validation framework.
精彩评论