Asp.net mvc 4 在FluentValidation中将子错误传播到父错误

Asp.net mvc 4 在FluentValidation中将子错误传播到父错误,asp.net-mvc-4,fluentvalidation,razor-2,Asp.net Mvc 4,Fluentvalidation,Razor 2,环境: 我正在使用MVC4、Razor 2和FluentValidation.MVC4(3.4.6.0) 场景: 我有一个特定页面的复杂视图模型,该页面上还有一个子视图模型,如下所示: public class ProfileViewModel { public string FirstName {get; set;} public PhoneNumberViewModel Primary {get; set;} // ... other stuff ... // }

环境:
我正在使用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验证器,如下所示:

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.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添加错误?和/或它是否有效,但我是否做错了什么?我搜索了又搜索,但找不到满意的解决方案


谢谢你的时间

我发现了一个不同于我在问题中提到的臭烘烘的解决方案。它也不太理想,但我想我更喜欢它,而不是上面提供的解决方案。也许其他人也会同意,所以在给出更清晰的答案之前,这可能是有用的

我在
PhoneNumberViewModel
中添加了一个属性,该属性以格式化字符串的形式返回整个电话号码:

public string FullNumber
{
   get { return string.Format("{0}{1}{2}{3}", AreaCode, Exchange, Suffix, Extension); }
}
然后,除了每个组件属性的规则外,还可以将验证规则应用于此属性。如果仅将
.WithMessage()
应用于FullNumber属性,则最终将获得预期的验证消息(且仅一次)以及每个框的文本框高亮显示(如果出现故障)

这种方法的主要缺点是最终会重复验证规则。您单独验证每个组件,然后还必须验证组合属性,这基本上是您已经完成的验证的组合。代码翻倍,处理量翻倍。你还将可能出现问题的地方数量增加了一倍


在我的例子中,我使用正则表达式,所以这并不太糟糕。。。我更喜欢在控制器中嵌入错误传播代码。然而,这仍然不理想-希望会有更好的解决方案。

我等了一周才接受自己不太理想的解决方案。最终,我认为最好的解决方案是删除自动验证连接,并始终手动设置验证。不幸的是,在这种情况下,我没有选择。
public string FullNumber
{
   get { return string.Format("{0}{1}{2}{3}", AreaCode, Exchange, Suffix, Extension); }
}