06.05
I’ve been working on xVal for WebForms without xVal in the jQuery.Validate branch. So far I’ve got basic server and client side validation for most data annotations validation attributes and server side validation for IValidatableObject implementers. The only challenging part so far was understanding how to serialize the validation rules for the jQuery Validate add method.
$("#txtClientName").rules("add", { required: true, minlength: 5, messages: { required: "Client name is required.", minlength: "Client name must be at least 5 characters." } });
I finally decided to implement JavaScriptConverter, which is used with JavaScriptSerializer. The Serialize method is what takes the Rule collection and converts it into two separate dictionaries, one for rules and one for messages. This allows the JavaScriptSerializer to properly serialize the dictionaries for the add method options parameter.
public class RulesJavaScriptConverter : JavaScriptConverter { private readonly ReadOnlyCollection<Type> _supportedTypes = new ReadOnlyCollection<Type>(new List<Type>(new[] {typeof (RuleCollection)})); public override IEnumerable<Type> SupportedTypes { get { return _supportedTypes; } } public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) { throw new NotSupportedException(); } public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) { return Serialize(obj as RuleCollection, serializer); } public IDictionary<string, object> Serialize(RuleCollection rules, JavaScriptSerializer serializer) { if (rules == null) { throw new ArgumentNullException("rules"); } Dictionary<string, object> options = rules.ToDictionary<Rule, string, object>(rule => rule.Name, rule => rule.Options); Dictionary<string, string> messages = rules.ToDictionary(rule => rule.Name, rule => rule.Message); Dictionary<string, object> result = new Dictionary<string, object>(options) {{"messages", messages}}; return result; } }
And here’s how I’m using it.
StringBuilder validationOptionsScript = new StringBuilder(); validationOptionsScript.AppendFormat("$('#{0}').rules('add', ", _controlToValidateId); JavaScriptSerializer serializer = new JavaScriptSerializer(); serializer.RegisterConverters(new[] {new RulesJavaScriptConverter()}); serializer.Serialize(rules, validationOptionsScript); validationOptionsScript.AppendLine(");");
The next step will be figuring out validation groups. I also plan on renaming the project. My best idea so far is jQuey Validate.NET. It’s not the most creative, but it gets the point across.
Hi John, I’m working on a library that is almost identical.
I am using a custom attribute on the control that gets parsed and creates the jQuery rule option. For example:
or
One of the hurdles I’m facing is tying in .Net’s existing Validate and IsValid methods. So that I can validate server side as well. Do you have any thoughts on this?
the html tags got erased…
asp:textbox runat=”server” id=”txtName” validate=”required”
—
asp:textbox runat=”server” id=”txtRange” validate=”{ required: true, range: { min: 0, max: 5, message: ‘Value must be between 0 and 5.’} }”
I think it would be much easier to build your client side rules based on server side rules. xVal for WebForms uses DataAnnotations to built both server and client side rules and runs server side validation in a validator base class.
http://xvalwebforms.codeplex.com/SourceControl/changeset/view/15f79e1f00b8#xVal.WebForms%2fModelPropertyValidator.cs