MVC 3 中的流畅验证和集合验证问题

发布于 2024-11-28 13:18:17 字数 3337 浏览 1 评论 0原文

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

我已经配置了 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])
}

I'm hoping I'm missing something simple here.

I've configured Fluent Validation for integration with MVC and it's been working quite well up until now. I'm now working on a scenario where a user is performing a standard create of what's called a "service". A service has hours that have to be defined.

The view model for this Create action is defined as follows:

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

and CreateServiceHoursViewModel is defined as...

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

The quick and dirty version of the UI ends up as follows:

enter image description here

The problem:

The fluent validation messages for the collection of hours are not showing the expected error message. They're displaying the standard error messages from Fluent Validation.

Here are my validators:

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

and the 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...");
    }
}

and with errors on the hours collection:

enter image description here

When I run the validate method manually in my controller action the correct error messages are returned...

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

This returns the messages I'd expect.

What am I missing or doing incorrect that the error messages for the hours collection from the fluent validations aren't being persisted to my view? (The main object validators work as expected)

Any info appreciated!

(I can update with my view if needed. I felt this question was plenty long already. Suffice it to say I have a view that uses an editor template to iterate the collection of service hours.)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毁梦 2024-12-05 13:18:18

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

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

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

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

(cross-posted to http://fluentvalidation.codeplex.com/discussions/267990)

The error messages you're seeing aren't coming from FluentValidation.

"The value is not valid for CloseTime" is an MVC error message that is generated before FluentValidation has a chance to kick in.

This is happening because FluentValidation works by validating the entire object once all the properties have been set, but in your case the string "*Enter closing time here" is not a valid DateTime, therefore MVC cannot actually set the property to a valid datetime, and generates an error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文