Created
April 7, 2011 13:14
-
-
Save joeriks/907766 to your computer and use it in GitHub Desktop.
Using a generic html form builder with client side and server side validation (Fluent Validation)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using HtmlFormAndValidation | |
<h2> | |
Header | |
</h2> | |
@{ | |
// create a customer object - see Models.cs | |
Customer customer = new Customer(); | |
// create a validation object with some rules - see Models.cs | |
CustomerValidator validator = new CustomerValidator(); | |
// create a form | |
var customerForm = new HtmlFormHelpers.HtmlFormDescriptor("customer-form"); | |
// add the fields I want to have in my Html form | |
customerForm.Add("Forename"); | |
customerForm.Add("Surname"); | |
customerForm.Add("EmailAddress"); | |
customerForm.Add("Submit", "Skicka in", "submit"); | |
// re-use fluent validator rules to automatically create some client rules | |
customerForm.AddFluentValidationRules<Customer>(validator); | |
// take care of post data | |
if (IsPost) | |
{ | |
// update the model with form data - at thist point we're already past the client side validation | |
HtmlFormHelpers.HtmlFormDescriptor.TryUpdateModel<Customer>(Request.Form, ref customer); | |
// do the server side validation with fluent validator | |
var validateResult = validator.Validate(customer); | |
if (!validateResult.IsValid) | |
{ | |
<p> | |
Errors:<ul> | |
@foreach (var r in validateResult.Errors) | |
{ | |
<li>@r.ErrorMessage</li> | |
} | |
</ul> | |
</p> | |
@Html.Raw(customerForm.Html(customer)) | |
} | |
if (validateResult.IsValid) | |
{ | |
<p><strong>Validated and ready to store in the db !</strong></p> | |
} | |
} | |
else | |
{ | |
@Html.Raw(customerForm.Html(customer)) | |
} | |
} | |
@* Client side validation with the help of jQuery validate*@ | |
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.2.min.js"></script> | |
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8/jquery.validate.min.js"></script> | |
<script type="text/javascript"> | |
jQuery(document).ready(function() { | |
jQuery("#customer-form").validate({@customerForm.jQueryValidateRulesJson()}); | |
} | |
) | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using FluentValidation; | |
using System.Collections.Specialized; | |
namespace HtmlFormHelpers | |
{ | |
public class HtmlFormDescriptor | |
{ | |
public class HtmlFieldDescriptor | |
{ | |
public string LabelText { get; set; } | |
public string Type { get; set; } | |
public string FieldName { get; set; } | |
public bool Required { get; set; } | |
public bool Email { get; set; } | |
public int MinLength { get; set; } | |
public int MaxLength { get; set; } | |
} | |
public List<HtmlFieldDescriptor> Fields { get; set; } | |
public string Name { get; set; } | |
public HtmlFormDescriptor(string name) | |
{ | |
Name = name; | |
Fields = new List<HtmlFieldDescriptor>(); | |
} | |
public void Add(string fieldName, string labelText = "", string type = "text", bool required = false, bool email = false, bool isNumeric = false, int maxLength = 0, int minLength = 0) | |
{ | |
var f = new HtmlFieldDescriptor(); | |
f.FieldName = fieldName; | |
f.LabelText = labelText; | |
f.Type = type; | |
f.Required = required; | |
f.Email = email; | |
f.MinLength = minLength; | |
f.MaxLength = maxLength; | |
Fields.Add(f); | |
} | |
public void AddFluentValidationRules<T>(FluentValidation.AbstractValidator<T> validator) | |
{ | |
foreach (FluentValidation.Internal.PropertyRule v in validator) | |
{ | |
var propertyName = v.PropertyName; | |
var x = v.PropertyDescription; | |
var currentValidator = v.CurrentValidator.ToString(); | |
if (Fields != null) | |
foreach (var h in Fields) | |
{ | |
if (h.FieldName == propertyName) | |
{ | |
if (currentValidator == "FluentValidation.Validators.NotNullValidator") | |
h.Required = true; | |
if (currentValidator == "FluentValidation.Validators.NotEmptyValidator") | |
h.Required = true; | |
if (currentValidator == "FluentValidation.Validators.EmailValidator") | |
{ h.Email = true; h.Required = true; } | |
if (h.LabelText == "" && v.PropertyDescription != "") | |
h.LabelText = v.PropertyDescription; | |
} | |
} | |
} | |
} | |
public string Html(object model = null, string action = "#", string method = "post") | |
{ | |
string retval = "<form id=\"" + Name + "\" method=\"" + method + "\" action=\"" + action + "\">\n"; | |
foreach (var h in Fields) | |
{ | |
var labelText = ""; | |
if (h.LabelText == "") labelText = h.FieldName; else labelText = h.LabelText; | |
retval += "<div class=input1>"; | |
if (h.Type == "text") | |
{ | |
retval += "<label for =" + h.FieldName + ">" + labelText + "</label>"; | |
string value = ""; | |
if (model != null) | |
{ | |
foreach (var p in model.GetType().GetProperties()) | |
{ | |
if (p.Name == h.FieldName) | |
{ | |
object v = p.GetValue(model, null); | |
if (v != null) | |
value = v.ToString(); | |
} | |
} | |
} | |
retval += "<input type=" + h.Type + " id=" + h.FieldName + " name=" + h.FieldName + " value=\"" + value + "\"/>"; | |
} | |
if (h.Type == "submit") | |
{ | |
retval += "<input type=" + h.Type + " id=" + h.FieldName + " name=" + h.FieldName + " value=\"" + labelText + "\"/>"; | |
} | |
retval += "</div>"; | |
} | |
retval += "</form>\n"; | |
return retval; | |
} | |
public string jQueryValidateRulesJson() | |
{ | |
var jsonString = "rules: {\n"; | |
var rules = ""; | |
foreach (var h in Fields) | |
{ | |
var fieldRules = ""; | |
if (h.Required) | |
{ | |
fieldRules += "required:true,"; | |
} | |
if (h.Email) | |
{ | |
fieldRules += "email:true,"; | |
} | |
if (h.MaxLength != 0) | |
{ | |
fieldRules += "maxlength:" + h.MaxLength.ToString() + ","; | |
} | |
if (h.MinLength != 0) | |
{ | |
fieldRules += "minlength:" + h.MinLength.ToString() + ","; | |
} | |
if (fieldRules != "") | |
{ | |
fieldRules = fieldRules.TrimEnd(','); | |
if (rules != "") { rules += ",\n"; } | |
rules += h.FieldName + ": {"; | |
rules += fieldRules + "}"; | |
} | |
} | |
jsonString += rules; | |
jsonString += "}\n"; | |
return jsonString; | |
} | |
public static void TryUpdateModel<T>(NameValueCollection dictionary, ref T model) | |
{ | |
foreach (var p in model.GetType().GetProperties()) | |
{ | |
if (dictionary.AllKeys.Contains(p.Name)) | |
{ | |
p.SetValue(model, dictionary[p.Name], null); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using FluentValidation; | |
namespace HtmlFormAndValidation | |
{ | |
public class Customer | |
{ | |
public int Id { get; set; } | |
public string Surname { get; set; } | |
public string Forename { get; set; } | |
public decimal Discount { get; set; } | |
public string EmailAddress { get; set; } | |
} | |
public class CustomerValidator : AbstractValidator<Customer> | |
{ | |
public CustomerValidator() | |
{ | |
RuleFor(customer => customer.Surname).NotEmpty().WithName("Efternamn"); | |
RuleFor(customer => customer.Forename).NotEmpty().WithName("Förnamn"); | |
RuleFor(customer => customer.EmailAddress).NotEmpty().EmailAddress().WithName("E-post"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment