开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜