MVC3 Unobtrusive Validation With MVC Contrib
Validation was a weakness of MVC until MVC3 came out with unobtrusive validation support. However, to get this feature you had to use the Microsoft provided MVC helpers. Having used MVC Contrib's helpers for a while, I found it frustrating to go back to the out of the box html helpers from Microsoft. After spending some time playing with it and doing research, I came up with a solution that I'm quite happy with that allows adding the unobtrusive validation attributes to the MVC Contrib controls.
The Markup
<% using (Html.BeginForm<HomeController>(a => a.Contrib())){ %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>TestModel</legend>
<div>
<%: Html.TextBox(a=>a.FirstName).Disabled(false) %>
<%: Html.ValidationMessageFor(a=>a.FirstName) %>
</div>
<div>
<%: Html.DropDownList(a=>a.SomeValue).Options(Model.ListOfSomething,a=>a.Id,a=>a.Name) %>
<%: Html.ValidationMessageFor(a => a.SomeValue)%>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
Contrib Extensions
public static class MvcFavoritesExtensions
{
public static MvcContrib.FluentHtml.Elements.TextBox TextBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
return new TextBox(expression.GetNameFor()).AddValidationAttributes(htmlHelper, expression);
}
public static MvcContrib.FluentHtml.Elements.Select DropDownList<TModel,TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
return new Select(expression.GetNameFor()).AddValidationAttributes(htmlHelper, expression);
}
public static MvcContrib.FluentHtml.Elements.CheckBox CheckBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
return new CheckBox(expression.GetNameFor()).AddValidationAttributes(htmlHelper, expression);
}
private static T AddValidationAttributes<T, TModel, TProperty>(this FormElement<T> element, HtmlHelper htmlHelper, Expression<Func<TModel, TProperty>> expression) where T : FormElement<T>
{
var validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression));
foreach (var attr in validationAttributes)
{
element.Attr(attr.Key, attr.Value);
}
return (T)element;
}
}
A Sample ViewModel
public class TestModel
{
[Required(ErrorMessage = "First Name is Required")]
public string FirstName { get; set; }
public IEnumerable<SomeObject> ListOfSomething { get; set; }
[DisplayName("Some Value")]
[Range(2,5,ErrorMessage = "Must be second or higher")]
public int SomeValue { get; set; }
}
The Rendered Markup
<form action="/Home/Contrib" method="post">
<fieldset>
<legend>TestModel</legend>
<div>
<input data-val="true" data-val-required="First Name is Required" id="FirstName" name="FirstName" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
</div>
<div>
<select data-val="true" data-val-number="The field Some Value must be a number." data-val-range="Must be second or higher" data-val-range-max="5" data-val-range-min="2" data-val-required="The Some Value field is required." id="SomeValue" name="SomeValue"><option value="1">First</option><option value="2">Second</option></select>
<span class="field-validation-valid" data-valmsg-for="SomeValue" data-valmsg-replace="true"></span>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
</form>
More writing
AI Model Regulation (Fable, GPT-5.6, OSS)
We used to celebrate new AI models, but lately releases are being delayed, restricted, or slow-rolled over national security concerns. Should AI be regulated, and if so, by whom?
Clustered Indexes and Performance
One of the most overlooked aspects of database design that I see from most application developers is the clustered index. Let us take a moment to discuss why this detail is so important, and to walk through some examples.
I'm BACK!
After a brief 8-year break, I decided to start blogging again! Here is what motivated me to start.
Getting Started with the Telerik MVC Extensions
A review of my experience using the Telerik MVC Extensions on several real world projects and instructions for integrating the Telerik MVC Extensions into your ASP.Net MVC project.
Codemash 2012 Recap & Pictures
Codemash Recap and Event Photos from Codemash 2012 including misc event photos, pictures of humorous Tweets on the large screen, a few presentations and the Pecha Kucha talks