asp.net-mvc - MVC 3 中的流畅验证和集合验证问题

标签 asp.net-mvc asp.net-mvc-3 model-binding fluentvalidation

我希望我在这里错过了一些简单的东西。

我已经配置了 Fluent Validation 以与 MVC 集成,并且到目前为止它一直运行良好。我现在正在研究一个场景,其中用户正在执行所谓的“服务”的标准创建。服务有必须定义的时间。

此创建操作的 View 模型定义如下:

[Validator(typeof (CreateServiceViewModelValidator))]
public class CreateServiceViewModel
{
    public string Name { get; set; }
    //...Other properties...
    public Collection<CreateServiceHoursViewModel> ServiceHours { get; set; }
}

并且 CreateServiceHoursViewModel 定义为...

public class CreateServiceHoursViewModel
{
    //...Other properties...
    public DayOfWeek DayOfWeekId { get; set; }
    public DateTimeOffset? OpenTime { get; set; }
    public DateTimeOffset? CloseTime { get; set; }
}

快速而肮脏的 UI 版本最终如下:

enter image description here

问题:

小时集合的流畅验证消息未显示预期的错误消息。它们显示来自 Fluent Validation 的标准错误消息。

这是我的验证器:

public class CreateServiceViewModelValidator : AbstractValidator<CreateServiceViewModel>
{
    public CreateServiceViewModelValidator()
    {
        RuleFor(f => f.Name).NotEmpty()
            .WithMessage("You must enter a name for this service.");

        RuleFor(f => f.Description)
            .NotEmpty().WithMessage("Service must have a description")
            .Length(3, 256).WithMessage("Description must be less than 256 characters.");

        RuleFor(f => f.ServiceHours).SetCollectionValidator(new CreateServiceHoursViewModelValidator());
    }
}

和 HoursValidator

public class CreateServiceHoursViewModelValidator : AbstractValidator<CreateServiceHoursViewModel>
{
    public CreateServiceHoursViewModelValidator()
    {
        DateTimeOffset test;
        DayOfWeek enumTest;

        RuleFor(r => r.DayOfWeekId).Must(byteId => Enum.TryParse(byteId.ToString(), out enumTest)).WithMessage("Not a valid day of week...");

        RuleFor(f => f.OpenTime)
            .NotEmpty().WithMessage("Please specify an opening time...")
            .Must(openTime =>
                  DateTimeOffset.TryParse(openTime.HasValue ? openTime.Value.ToString() : String.Empty, out test))
            .WithMessage("Not a valid time...");

        RuleFor(f => f.CloseTime)
            .NotEmpty().WithMessage("Please specify a closing time...")
            .Must(closeTime =>
                  DateTimeOffset.TryParse(closeTime.HasValue ? closeTime.Value.ToString() : String.Empty, out test))
            .WithMessage("Not a valid time...");
    }
}

并且在时间收集上有错误:

enter image description here

当我在 Controller 操作中手动运行验证方法时,会返回正确的错误消息...

var validator = new CreateServiceViewModelValidator();
var results = validator.Validate(model);

foreach (var result in results.Errors)
{
    Console.WriteLine("Property name: " + result.PropertyName);
    Console.WriteLine("Error: " + result.ErrorMessage);
    Console.WriteLine("");
}

这会返回我期望的消息。

我错过了什么或做错了什么,导致流畅验证中的小时数收集的错误消息没有保留在我的 View 中? (主要对象验证器按预期工作)

任何信息表示赞赏!

(如果需要,我可以更新我的 View 。我觉得这个问题已经很长了。只要说我有一个使用编辑器模板来迭代服务时间集合的 View 就足够了。)

@for (int weekCounter = 0; weekCounter <= 6; weekCounter++)
{
    @Html.DisplayFor(model => model.ServiceHours[weekCounter])
}

最佳答案

(交叉发布到 http://fluentvalidation.codeplex.com/discussions/267990 )

您看到的错误消息不是来自 FluentValidation。

“The value is not valid for CloseTime”是在 FluentValidation 有机会启动之前生成的 MVC 错误消息。

发生这种情况是因为 FluentValidation 的工作原理是在设置所有属性后验证整个对象,但在您的情况下,字符串“*在此处输入关闭时间”不是有效的日期时间,因此 MVC 实际上无法将属性设置为有效的日期时间,并生成错误。

关于asp.net-mvc - MVC 3 中的流畅验证和集合验证问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6961744/

相关文章:

asp.net-mvc - 自定义授权属性(后续)

asp.net-mvc - 产品目录搜索 - NoSQL/MongoDB 的良好用例?

asp.net-mvc-3 - 发布表单时 Controller 中的模型绑定(bind) - 导航属性不会自动加载

c# - 更改整数的默认 NumberStyles?

c# - 如何在通过 QuickBooks Online API 添加客户之前检查客户是否存在?

asp.net - 文件路径作为 MVC 路由参数

c# - ContentResult 与 JsonResult 与 ajax

c# - 为什么此代码会抛出 InvalidOperationException?

c# - 如何制作可以接受来自外部站点的请求的 ASP.NET MVC Controller ?

c# - MVC2 TextBoxFor 值在提交后没有更新?