Connect [SelfValidation] with Views to present the ValidationResults

Topics: Validation Application Block
Feb 25, 2011 at 4:49 PM

Is is possible? I want to validate my BusinessEntity with [SelfValidation[ and to present ValidationResult in View. (There is an ASP.NET WebSite with EnterpiseLibrary 5.)

 

Maybe there are some opportunities to write the ValdationResults in Page.. Or something like this?

 

 

 

 

 

 

Feb 26, 2011 at 10:52 PM
Edited Feb 27, 2011 at 11:07 PM

What you can do is throw an exception when validation fails. When you wrap the ValidationResult objects in a custom exception (say ValidationException), you can catch that specific exception in the presentation layer and present that to the client in a fairly simple way. Look for instance at the example below:

// Code in your Page class.
try
{
    // Execute business logic that might throw an ValidationException.
}
catch (ValidationException ex)
{
    WebValidationHelper.DisplayValidationErrors(ex.Errors);
}

// Helper class that allows adding validation errors to the page.
public static class WebValidationHelper
{
    public static void DisplayValidationErrors(IEnumerable<ValidationResult> results)
    {
        Page page = (Page)HttpContext.Current.CurrentHandler;
        var ValidationSummary = page.Controls.OfType<ValidationSummary>().First();

        foreach (var result in e.Error.Results)
        {
            ValidationSummary.Controls.Add(new CustomValidator
            {
                ErrorMessage = result.Message,
                IsValid = false
            });
        }
    }
}

For this to work you would need a ValidationSummary on the page.

An even nicer solution would be possible when you wrap you business logic in commands that can be executed from within the presentation layer. When you do that you can expose an event in those commands that allows you to get notified when a validation failure happens. This would allow you to write your presentation code as follows:

// Create a command
var command = new CreateAnonymousNewsItemCommentCommand()
{
	ItemId = this.NewsItem.ItemId,
	UserIpAddress = this.Request.UserHostAddress,
	UserName = this.textCommentorName.Text,
	UserEmail = this.textCommentorEmail.Text,
	Comment = this.textComment.Text
};

// Create a handler for that command type
var commandHandler = this.handlerFactory.CreateNew<CreateAnonymousNewsItemCommentCommand>();

// Hook to the validation error event
commandHandler.ValidationErrorOccurred += WebValidationHelper.DisplayValidationErrors;

// execute the command.
commandHandler.Handle(command);

The DisplayValidationErrors method could in that case look like this:

public static class WebValidationHelper
{
    public static void DisplayValidationErrors(object sender, ValidationErrorEventArgs e)
    {
        Page page = (Page)HttpContext.Current.CurrentHandler;
        var ValidationSummary = page.Controls.OfType<ValidationSummary>().First();

        foreach (var result in e.Error.Results)
        {
            ValidationSummary.Controls.Add(new CustomValidator
            {
                ErrorMessage = result.Message,
                IsValid = false
            });
        }
        e.Handled = true;
    }
}

When you do this, make sure that the handlers (or handler base class) checks whether an event is handled (the e.Handled = true) and if not, it should throw an exception indicating that validation failed. This would make sure that validation errors won't get lost if no one is handling them.

I hope this helps.

Cheers

Mar 1, 2011 at 10:37 AM

thank you for your answer! =)

 

 

We have found our way - a reference to Business Entity in View. And each Business Entity with [SelfValidation] has also ValidationResults Property.