.Net RIA Services: Custom Validation
.Net RIA Services: Custom Validation
This is another post in a series of posts about building applications with Microsoft .Net RIA Services and Silverlight 3 and ASP.Net.
- Build a Simple Application with .Net RIA Services (Silverlight 3) – Part 1
- Build a Simple Application with .Net RIA Services (Silverlight 3) – Part 2
- .Net RIA Services Part 3: DataForm and Validation
- .Net RIA Services: Sharing Code between the Client and Server
- Using DomainDataSource in ASP.Net
- ASP.Net DomainDataSource with Select Parameters
- ASP.Net QueryExtender Control and DomainDataSource
In my previous post .Net RIA Services Part 3: DataForm and Validation I explained how to add validation metadata to entities and showed how the DataForm control enforces them. I used simple validation metadata attributes such as RegularExpressionAttribute, RequiredAttribute and StringLengthAttribute that help us in basic scenarios.
If you want to write custom validation, you can inherit from System.ComponentModel.DataAnnotations.ValidationAttribute, but a more simple way would be to write a validation method, and share it between the server side and the client side, as I explained in my previous post .Net RIA Services: Sharing Code between the Client and Server.
In CustomerValidation.shared.cs file (in the server side) I wrote the following method, that takes the value of a property and returns an indication whether it is valid or not.
[Shared]
public class CustomerValidation
{
[Shared]
public static bool IsEmailEndsWithDotCom(string email)
{
if (email.EndsWith(".com"))
return true;
return false;
}
}
To apply this validation logic on an entity property, use the CustomValidationAttribute with the about type and method name, and the error message to display.
internal sealed class CustomerMetadata
{
...
[CustomValidation(typeof(CustomerValidation),
"IsEmailEndsWithDotCom",
ErrorMessage = "Customer\'s email address must end with .com")]
public string Email;
...
}
At runtime, the framework will invoke this method passing it the property value, and if it returns False, the error message will be shown.
The above sample is also nice for scenarios is which the logic is independent of any other property about the entity that’s being validated. In cases where you need additional information about the entity to perform the validation logic, you can use a more complex signature of the validation method.
[Shared]
public class CustomerValidation
{
[Shared]
public static bool EnsureBusinessEmailAddress(string email,
ValidationContext ctx,
out ValidationResult result)
{
result = null;
Customer cust = (Customer)ctx.ObjectInstance;
if (cust.IsBusiness)
{
if (!cust.Email.EndsWith(".com"))
{
result = new ValidationResult("Business Customer's email address must end with .com");
}
}
return false;
}
}
In this approach I receive not only the property value, but also an instance of ValidationContext that provides me with some information about the entity and property being validated and also a reference to the entity instance itself.
Using it is the same, except that here I pass the error message in the out parameter ValidationResult, instead of providing it in the validation attribute.
internal sealed class CustomerMetadata
{
...
[CustomValidation(typeof(CustomerValidation), "EnsureBusinessEmailAddress")]
public string Email;
...
}
Enjoy!