mvc clientside validation for nested (collection) properties
I'm using asp.net mvc 3 with jquery unobtrusive validation. I recently changed from standard DataAnnotations to FluentValidation and it works great.
My primary reason for picking up FluentValidation was the need to validate nested properties on my viewmodel (but i found there are other cool reasons for using it) that kinda looks like this (don't mind accessors this is pseudo):
class Vm {
string Prop;
string AnotherProp;
IEnumerable<ElementsVm> Elements;
}
class ElementsVm {
bool Required;
string Id;
string Title;
string Value;
}
Using FluentValidation I make a validator for Vm and for ElementVm and my unit tests are green, showing me server side validation is working.
Client side, 'Prop' and 'AnotherProp' is working - my validation rules are also running client-side as expected (as they would with DataAnnontation), but all my Elements are not getting any client-side validation at all - i inspect the dom and can see all the data-val, data-required etc. attributes are missing.
I've tried different approaches to generating the html in my views, but the 'Prop' and 'AnotherProp' are generated using Html.TextBoxFor(m => m.Prop) while my elements are generated in a partial - this is where the problems start. If i choose Html.TextBoxFor(m => m.Value) all my Element Textboxes will have the same name/id, so i also tried using Html.TextBox(Model.Id) to generate unique id/name but still no validation properties.
So is there a way to make my senario work - i don't mind rewriting it a bit, but i would really like FluentValidation to write my html for me.
My fallback solution would be to开发者_运维问答 make my own Html helpers to generate the correct Html with attributes, but that would suck i think, since i would have to keep updating those helpers when new releases/patches were made to either FluentValidation, jquery validation or the link in mvc between the two.
In your partial, before each instance of ElementsVM, you must set a unique prefix using ViewData.TemplateInfo.HtmlFieldPrefix, like so:
var i = 0;
foreach (var element in Model)
{
ViewData.TemplateInfo.HtmlFieldPrefix = "Elements[" + i.ToString() + "]";
@Html.TextBoxFor(m => m.Value)
i++;
}
This should give you your unobtrusive validation attributes, and should also work with the default model binder.
counsellorben
精彩评论