Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
393 views
in Technique[技术] by (71.8m points)

asp.net mvc 3 - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...