Han*_*fer 7 validation asp.net-mvc fluentvalidation asp.net-mvc-5
我使用FluentValidation来验证我的ASP.NET MVC 5.1视图模型(使用默认的不显眼的客户端验证).我通过Ninject注册/创建我的验证器(viewmodels上没有属性):
FluentValidationModelValidatorProvider.Configure(x => x.ValidatorFactory = new NinjectValidatorFactory(_kernel));
AssemblyScanner.FindValidatorsInAssembly(Assembly.GetExecutingAssembly()).ForEach(match => _kernel.Bind(match.InterfaceType).To(match.ValidatorType));
Run Code Online (Sandbox Code Playgroud)
我有一个在整个应用程序中经常使用的局部视图.此部分视图具有自己的视图模型."主"视图模型(整个视图的视图模型)只是从这个"部分"视图模型继承而来.
public class IndexViewModel : PersonalInfoViewModel { ... }
Run Code Online (Sandbox Code Playgroud)
验证器使用相同的模式:
public class IndexValidator : PersonalInfoValidator { ... }
Run Code Online (Sandbox Code Playgroud)
这工作正常,服务器端验证以及"主"视图上的客户端验证工作.但是不会触发部分视图的客户端验证(data-val-*输入字段上没有属性).
我的"主要"观点 Index.cshtml
@model IndexViewModel
@Html.TextBoxFor(x => x.SomeProperty) // client-side validation works fine
@Html.Partial("PersonalInfo") // client-side validation in the partial view does not work (see below)
Run Code Online (Sandbox Code Playgroud)
我的部分观点PersonalInfo.cshtml:
@model PersonalInfoViewModel
@Html.TextBoxFor(x => x.FirstName) // client-side validation does not work
Run Code Online (Sandbox Code Playgroud)
我注意到当我将局部视图的模型更改为"main"viewmodel时它可以工作:
@model IndexViewModel
@Html.TextBoxFor(x => x.FirstName) // client-side validation works
Run Code Online (Sandbox Code Playgroud)
所以我想在构建客户端验证的某个地方,正确的验证器没有被拾取,并且没有data-val-*属性被注入到HTML中.但是我无法更改局部视图上的viewmodel,因为它在具有不同"主"视图的几个不同页面上使用(尽管都是从PersonalInfoViewModel继承).
关于如何在这种情况下使我的客户端验证工作的任何想法?
更新
在挖掘ASP.NET WebStack源几个小时之后,我发现问题似乎发生在该TextBoxFor方法中.在那里,ModelMetaData从模型建立-在那里的某个地方,它开始使用IndexViewModel的,而不是PersonalInfoViewModel来获取客户端验证的元数据:
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Html.GetUnobtrusiveValidationAttributes("FirstName", metadata); // no client-side validation attributes found
Run Code Online (Sandbox Code Playgroud)
但是,如果我没有明确指定元数据,则会生成正确的客户端验证属性:
Html.GetUnobtrusiveValidationAttributes("FirstName");
Run Code Online (Sandbox Code Playgroud)
不幸的是,到目前为止,我还没有找到一种方法来利用这些知识.
我无法找到一个很好的解决方案来解决我的问题,并且不想再使用 ASP.NET WebStack 源代码,所以我采用了一个丑陋的解决方法:
data-val-*我在渲染输入字段时“手动”注入缺少的属性,如下所示:
@Html.TextBoxFor(x => x.FirstName, Html.GetUnobtrusiveValidationAttributes("FirstName"))
Run Code Online (Sandbox Code Playgroud)
由于GetUnobtrusiveValidationAttributes(称为独立)构建了正确的 HTML 属性,我只需将它们添加到 TextBox 中即可。绝对不漂亮,但它有效,我可以继续我的工作。如果有人有更好的解决方案,我会很高兴听到。