Revisit UI Validation

Central validation is not practical, distributed validation is OK as long as they are centrally controlled, e.g., through CI, even simpler, a linked file among projects.

Attribute validation on DTO is perfect for UI/service input validation. But most validation attribute are not serializable, if shared assembly can not be used, the linked file contains core validation rules can be a work around, especially for Silverlight app.


// This can be duplicated in both service and UI
[RegularExpression(ValidationRules.PostCriteriaRules.KeywordRegex)]
public string Keyword { get; set; }

// The core rule is defined in shared/linked file
    public static class ValidationRules
    {
        public static class PostCriteriaRules
        {
            public const string KeywordRegex = @"^[a-zA-Z0-9]{3,}$";
        }
    }

For WPF/Silverlight, an extension method to IDataError can be used to simply wire up code:

public static class DataAnnotationValidator
    {
        public static string ValidateProperty(this IDataErrorInfo viewModel, string columnName)
        {
            PropertyInfo prop = viewModel.GetType().GetProperty(columnName);

            IEnumerable validationMap = prop
                .GetCustomAttributes(typeof(ValidationAttribute), true)
                .Cast()
                ;

            foreach (ValidationAttribute v in validationMap)
            {
                try
                {
                    v.Validate(prop.GetValue(viewModel, null), new ValidationContext(viewModel, null, null) { MemberName = columnName });
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }

            return null;
        }
    }

 public class ShellViewModel : Conductor.Collection.OneActive, IShellViewModel,  IDataErrorInfo
    {....

 public string this[string columnName]
        {
            get {
                return this.ValidateProperty(columnName);
            }
        }

        public string Error
        {
            get { throw new NotImplementedException(); }
        }
    }

It would be nice if the Silverlight version of DataAnnotation can support MetadataType, then we can share the whole validation file.

MetadataType can be a solution if you want to re-do the same input validation in domain model, I don’t know why people want to do this. considering that most the property in domain model should not have setter.

 [MetadataType(typeof(PostCriteriaValidation))]
    public class ShellViewModel : Conductor.Collection.OneActive, IShellViewModel,  IDataErrorInfo
    {...

To use DataAnnotation in Silverlight is very simple:

<TextBox Height="23" HorizontalAlignment="Left" Margin="12,33,0,0"   x:Name="Keywords" VerticalAlignment="Top" Width="120"  >
 <TextBox.Text>
 <Binding Path="Keywords"  Mode="TwoWay" ValidatesOnExceptions="true"  ValidatesOnDataErrors="true" NotifyOnValidationError="true" />
 </TextBox.Text>
 </TextBox>


On the other hand, DataAnnotation has very limited feature, we couldn’t make a simply start-date/end-date validation working.

NHibernate.Validator seems more powerful, but I’m not sure is it good for Silverlight. It also has dependency to log4net and NHibernate.

Advertisements

3 thoughts on “Revisit UI Validation

      • We are still using Csla, were are doing TDD but its a bit messy like you have probably seen. However using Csla with NHibernate and SQLite means we can get unit tests but they are more like fast integration tests.

        Good luck with your projects

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s