环境:
我正在使用 MVC4、Razor 2 和 FluentValidation.MVC4 (3.4.6.0)。
场景:
我有一个特定页面的复杂视图模型,它上面还有一个子视图模型,如下所示:
public class ProfileViewModel
{
public string FirstName {get; set;}
public PhoneNumberViewModel Primary {get; set;}
// ... other stuff ... //
}
public class PhoneNumberViewModel
{
public string AreaCode { get; set; }
public string Exchange { get; set; }
public string Suffix { get; set; }
public string Extension { get; set; }
}
可以编辑此配置文件并将其发回以进行更新。我为两者创建了 Fluent Validators,如下所示:
public class ProfileViewModelValidator : AbstractValidator<ProfileViewModel>
{
public ProfileViewModelValidator()
{
RuleFor(m => m.FirstName).NotEmpty().WithMessage("Please enter a First Name,");
RuleFor(m => m.Primary).SetValidator(new PhoneNumberViewModelValidator()).WithMessage("Hello StackOverflow!");
// ... other validation ... //
}
}
public class PhoneNumberViewModelValidator : AbstractValidator<PhoneNumberViewModel>
{
public PhoneNumberViewModelValidator()
{
RuleFor(m => m.AreaCode).NotEmpty();
}
}
然后,当然,我有视图来显示所有内容。
个人资料视图片段:
...
@Html.TextBoxFor(m => m.FirstName)
@Html.EditorFor(m => m.PrimaryPhoneNumber)
...
电话号码编辑器模板片段:
...
@Html.ValidationLabelFor(m => m, "Primary Phone:")
@Html.TextBoxFor(m => m.AreaCode)
@Html.TextBoxFor(m => m.Exchange)
@Html.TextBoxFor(m => m.Suffix)
@Html.TextBoxFor(m => m.Extension)
@Html.ValidationMessageFor(m => m)
...
如果它是相关的,我会设置一些东西,以便它自动将验证器与各种对象连接起来。实际上,我什至不需要.SetValidator()
上面的那一行……由于接线,一切都得到了验证。
目标:
如果我不输入名字,我会在 ValidationMessageFor 创建的区域中收到上面提供的错误消息。但是,如果子 PhoneNumberViewModel 的任何元素验证失败,我什么也得不到。文本框突出显示红色,这很棒,但我没有收到我在 中提供的消息.WithMessage()
,表明我的子属性无效。
目前我正在通过我的控制器中的额外工作来实现它......它在子对象上查找错误,然后将错误添加到父对象。这种方法闻起来非常非常糟糕。它将验证相关的问题放在控制器中,我只是不希望它们在那里。更不用说它最终也有大量的字符串索引来挖掘 ModelState,这只是......恶心。
是否有一种简单的方法可以为 ProfileViewModelValidator 定义验证规则,如果子验证失败,它将为 ProfileViewModel 添加错误?和/或它应该工作,但我做错了什么?我已经搜索和搜索,但我找不到满意的解决方案。
谢谢你的时间!