Skip to content

Instantly share code, notes, and snippets.

@joeriks
Created April 7, 2011 13:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joeriks/907766 to your computer and use it in GitHub Desktop.
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)
@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>
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);
}
}
}
}
}
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