MVC HtmlHelper 与 FluentValidation 3.1:获取 ModelMetadata IsRequired 时遇到问题
我为 Label 创建了一个 HtmlHelper,如果需要关联字段,则在该标签的名称后面放置一个星号:
public static MvcHtmlString LabelForR<TModel, TValue>(
this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
return LabelHelper(
html,
ModelMetadata.FromLambdaExpression(expression, html.ViewData),
ExpressionHelper.GetExpressionText(expression),
null);
}
private static MvcHtmlString LabelHelper(HtmlHelper helper, ModelMetadata metadata, string htmlFieldName, string text)
{
... //check metadata.IsRequired here
... // if Required show the star
}
如果我使用 DataAnnotations 并在 ViewModel 中的属性上单击 [Required],则我的私有 LabelHelper 中的metadata.IsRequired 将等于 True一切都会按预期进行。
但是,如果我使用 FluentValidation 3.1 并添加一个简单的规则,如下所示:
public class CheckEmailViewModelValidator : AbstractValidator<CheckEmailViewModel>
{
public CheckEmailViewModelValidator()
{
RuleFor(m => m.Email)
.NotNull()
.EmailAddress();
}
}
... 在我的 LabelHelper 元数据中。IsRequired 将被错误地设置为 false。 (验证器可以工作:您不能提交空字段,并且它需要是类似电子邮件的字段)。
其余元数据看起来正确(例如:metadata.DisplayName =“Email”)。
从理论上讲,如果使用 Rule .NotNull(),FluentValidator 会在属性上添加RequiredAttribute。
供参考: 我的 ViewModel:
[Validator(typeof(CheckEmailViewModelValidator))]
public class CheckEmailViewModel
{
//[Required]
[Display(Name = "Email")]
public string Email { get; set; }
}
我的控制器:
public class MemberController : Controller
{
[HttpGet]
public ActionResult CheckEmail()
{
var model = new CheckEmailViewModel();
return View(model);
}
}
感谢任何帮助。
I created a HtmlHelper for Label that puts a star after the name of that Label if associated field is required:
public static MvcHtmlString LabelForR<TModel, TValue>(
this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
return LabelHelper(
html,
ModelMetadata.FromLambdaExpression(expression, html.ViewData),
ExpressionHelper.GetExpressionText(expression),
null);
}
private static MvcHtmlString LabelHelper(HtmlHelper helper, ModelMetadata metadata, string htmlFieldName, string text)
{
... //check metadata.IsRequired here
... // if Required show the star
}
If I use DataAnnotations and slap [Required] on the property in my ViewModel, metadata.IsRequired in my private LabelHelper will be equal to True and everything will work as intended.
However, if I use FluentValidation 3.1 and add a simple rule like that:
public class CheckEmailViewModelValidator : AbstractValidator<CheckEmailViewModel>
{
public CheckEmailViewModelValidator()
{
RuleFor(m => m.Email)
.NotNull()
.EmailAddress();
}
}
... in my LabelHelper metadata.IsRequired will be incorrectly set to false. (The validator works though: you can't submit empty field and it needs to be an Email like).
The rest of the metadata looks correct (Ex: metadata.DisplayName = "Email").
In theory, FluentValidator slaps RequiredAttribute on property if Rule .NotNull() is used.
For references:
My ViewModel:
[Validator(typeof(CheckEmailViewModelValidator))]
public class CheckEmailViewModel
{
//[Required]
[Display(Name = "Email")]
public string Email { get; set; }
}
My Controller:
public class MemberController : Controller
{
[HttpGet]
public ActionResult CheckEmail()
{
var model = new CheckEmailViewModel();
return View(model);
}
}
Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
默认情况下,MVC 将 DataAnnotations 属性用于两个不同的目的 - 元数据和验证。
当您在 MVC 应用程序中启用 FluentValidation 时,FluentValidation 会挂钩到验证基础结构,但不会挂钩元数据 - MVC 将继续使用元数据的属性。如果您想使用 FluentValidation 进行元数据和验证,那么您需要编写 MVC 的 ModelMetadataProvider 的自定义实现,它知道如何询问验证器类 - 这不是 FluentValidation 开箱即用支持的东西。
By default, MVC uses the DataAnnotations attributes for two separate purposes - metadata and validation.
When you enable FluentValidation in an MVC application, FluentValidation hooks into the validation infrastructure but not metadata - MVC will continue to use attributes for metadata. If you want to use FluentValidation for metadata as well as validation then you'd need to write a custom implementation of MVC's ModelMetadataProvider that knows how to interrogate the validator classes - this isn't something that FluentValidation supports out of the box.
我有一个自定义的 ModelMetadataProvider,它增强了默认的 DataAnnotations,给出以下内容:
我确实检查了 Jeremy 准备的源代码,但我还没有准备好进行全面检修,因此我进行了混合和匹配,以免丢失默认行为。您可以在此处找到
这里是具有一些额外优点的代码取自 这篇文章。
I have a custom ModelMetadataProvider that enhances the default DataAnnotations one giving the following:
I definitely checked out the source code that Jeremy has prepared but I was not ready for a total overhaul so I mixed and matched in order not to lose the default behavior. You can find it here
Here is the code with some additional goodness taken from this post.