【问题标题】:Fluent Validation and Collection Validation Issues in MVC 3MVC 3 中的流利验证和集合验证问题
【发布时间】:2011-08-06 17:24:48
【问题描述】:

我希望我在这里遗漏了一些简单的东西。

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

这个 Create 动作的视图模型定义如下:

[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 版本如下:

问题:

小时集合的流畅验证消息未显示预期的错误消息。他们正在显示来自 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...");
    }
}

并且在小时集合上有错误:

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

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("");
}

这会返回我期望的消息。

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

感谢任何信息!

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

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

【问题讨论】:

  • 作为一个快速更新,我在 Fluent Validation 论坛上找到了这个帖子。 fluentvalidation.codeplex.com/discussions/266845 它似乎与我的可空类型问题可能相关。我将尝试在这里将值更改为不可为空的类型并报告回来。
  • 在可空类型方面没有骰子。

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


【解决方案1】:

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

您看到的错误消息并非来自 FluentValidation。

“该值对 CloseTime 无效”是在 FluentValidation 有机会启动之前生成的 MVC 错误消息。

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

【讨论】:

  • 啊,杰里米的电话很好。我继续通过将 Open 和 Close Time 属性转换为字符串并让 vaidator 对 DateTimeOffset 执行 TryParse 来测试这一点,我得到了预期的结果。这实际上效果很好,因为我使用 Date.js 允许用户在时间输入方面有一点灵活性。好电话,感谢您的回答!
猜你喜欢
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多