Umbraco Contour is a great package for ultra fast building of forms. What we used it for was not entirely what it was meant for.
We were asked to build a form where labels, validation messages AND the regular expressions to validate phone numbers were all regionalized. Contour uses Umbraco's dictionary to store regionalized labels, so we decided to store our validation messages and regex there. Here is how we did it all...
Firstly, we name our field's in the form #Form_FirstName, #Form_LastName etc. In the dictionary, add your languages. Then create items with the same names as the form fields (without the #). This allows Contour to replace your labels. We create two matching items to handle regionalized values for validation messages and regex: #Form_FirstName_vmsg, and #Form_FirstName_regex respectively.
Contour installs RenderForm.ascx under \usercontrols\umbracoContour\ in your project. Noticing this, you can easily change it's CodeBehind property to your own "RenderForm.ascx.cs" which you inherit from Contour's. Overriding OnPreRender() is where the magic happens. The code is pretty self explanatory. We override OnPreRender(), loop through the fields, use their caption property and a suffix ("_vmsg" or "_regex") to get the values from the dictionary.
Here is the code...
public class RenderForm : Umbraco.Forms.UI.Usercontrols.RenderForm
protected override void OnPreRender(EventArgs e)
// get the form fields
FormStorage fs = new FormStorage();
var form = fs.GetForm(new Guid(this.FormGuid));
var fields = form.AllFields;
foreach (var f in fields)
// get this field's validator
var fieldId = f.Id.ToString();
var vals = Page.Validators
.Where(x => x.ControlToValidate == fieldId).ToList();
if (vals.Count > 0)
foreach (var baseVal in vals)
// get the validator type and assign properties
BaseValidator val = baseVal as RegularExpressionValidator;
if (val != null) // it is RegularExpressionValidator
// get regionalized regular expression
string valExpression = GetRegionalizedValidationText(f.Caption, "_regex");
((RegularExpressionValidator)val).ValidationExpression = !string.IsNullOrEmpty(valExpression) ? valExpression : ((RegularExpressionValidator)val).ValidationExpression;
else // either a RequiredFieldValidator or another type which you must handle here!
// cast to another Validator type you are expecting, then set it's properties
// Get the error message
val = baseVal as BaseValidator;
if (val != null)
// get regionalized error message
string errorMessage = GetRegionalizedValidationText(f.Caption, "_vmsg");
val.ErrorMessage = !string.IsNullOrEmpty(errorMessage) ? errorMessage : val.ErrorMessage;
val.ValidationGroup = form.Name;
// Uses's the given string and suffix to get a value from the Umbraco dictionary.
public string GetRegionalizedValidationText(string key, string type)
string itemName = key.Split('#') + type;
if (umbraco.library.GetDictionaryItem(itemName) != null) // note: item can exist and be ""
return ""; // key does not contain #, or not found in dictionary