It looks like a legitimate bug, here's the best workaround I've found in my search:
http://forums.asp.net/t/1649193.aspx
In short. You wrap the source of the problem, DropDownListFor
, in a custom Html extension and you manually retrieve the unobtrusive clientside validation rules like this:
IDictionary<string, object> validationAttributes = htmlHelper.
GetUnobtrusiveValidationAttributes(
ExpressionHelper.GetExpressionText(expression),
metadata
);
Then you combine your validationAttributes
dictionary with any other html attributes passed into your custom helper and you pass that along to DropDownListFor
The complete code that I'm using (I have a label in there too, you can feel free to de-couple):
public static IHtmlString DropDownListWithLabelFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string label, IEnumerable<SelectListItem> items, string blankOption, object htmlAttributes = null)
{
var l = new TagBuilder("label");
var br = new TagBuilder("br");
var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
var mergedAttributes = helper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata);
if (htmlAttributes != null)
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
{
object value = descriptor.GetValue(htmlAttributes);
mergedAttributes.Add(descriptor.Name, value);
}
}
l.InnerHtml = label + br.ToString(TagRenderMode.SelfClosing) + helper.DropDownListFor(expression, items, blankOption, mergedAttributes);
return MvcHtmlString.Create(l.ToString(TagRenderMode.Normal));
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…