【问题标题】:Fluent Validation not working as expected with .Equal() test.Equal() 测试的流利验证无法按预期工作
【发布时间】:2018-11-01 20:06:28
【问题描述】:

我为客户视图模型创建了 FluentValidation (FV) 测试。 在模型中的测试是:

{RuleFor(x => x.Email).NotNull().EmailAddress().WithMessage("Email format is Invalid").DependentRules(() => {
            RuleFor(x => x.EmailExists).Equal(1).WithMessage("Email is already in use!");                
        });

因此,意味着要对电子邮件进行测试以确保其不为空并且是真正的电子邮件格式。然后,如果此测试通过,则依赖规则检查另一个字段以确保电子邮件不存在于 AspNetUsers 表中。我通过在页面 POST 方法期间进行测试来做到这一点,然后将模型传递给验证器进行检查,如下所示:

if (!string.IsNullOrEmpty(model.Email))
{
    var exists = _userService.UserExists(model.Email);
    model.EmailExists = exists ? 1 : 0;
}

CustomerAddViewModelValidator validator = new CustomerAddViewModelValidator();    
ValidationResult result = validator.Validate(model);

if (!result.IsValid) 
{
    model.ListTitles = GetTitlesList();              
    return View(model);
}

到目前为止一切顺利。电子邮件的初始测试正在运行,它进入依赖检查,这就是它的行为变得奇怪的地方:

行为是: 如果我使用:RuleFor(x => x.EmailExists).Equal(1) FV 总是报告好像电子邮件已经存在, 即使电子邮件没有

如果我使用RuleFor(x => x.EmailExists).Equal(0) FV 总是报告好像电子邮件不存在并且没有给出警告,即使电子邮件输入确实存在。

最初我在 HiddenFor 字段上进行此测试,但在阅读了有关 JS 不显眼验证的内容后,我在 Razor 网页上设置了 EmailExists 一个标签,直到我弄清楚为什么它没有报告正确的状态。

当电子邮件存在时:

所以您可以看到无论结果(0 或 1)是什么,FV 规则都在报告相同的消息。

有什么可以帮忙的吗?我尝试使用具有几乎相同结果的布尔值。我的所有其他验证都成功运行,所以我认为我可能没有使用正确的检查?

一如既往,提前致谢。

这是渲染的代码:

这是屏幕截图:

这是修改后的 RuleFor:

RuleFor(x => x.Email).NotNull().EmailAddress().WithMessage("Email format is Invalid").DependentRules(() => { RuleFor(x => x.EmailExists).Equal(0).WithMessage("Email is already in use!"); });

如您所见,规则是正确的,但我得到了相同的行为,其中结果为 1 或 ) 以及电子邮件是否存在......:

【问题讨论】:

  • 您是否调试过代码以确保 exists 确实是您认为的那样?
  • 嗨@JuanR 是的,在使用 FV 测试模型之前,我在 POST 控制器方法中创建了 Exists 值。我显示的图像中的 0 和 1 是 Exists 的值,传递给 Validation 类和验证失败时的视图。
  • 我明白这一点,但您是否真正调试过以验证 exists 是否为假?我知道这听起来很傻,但有时我们会假设一些事情。
  • 嗨 Juan,是的,就像我在问题中所说的那样,您可以在我发布的图片中电子邮件地址下方的标签中看到 EXISTS 的实际值。我正在做测试以检查用户是否存在作为 POST 方法中发生的第一件事,然后我相应地更新模型,然后调用 Fluent Validation。
  • 我认为问题与您如何填充 EmailExists 属性有关。我建议你阅读这篇文章,而不是试图让它工作,它基本上描述了一种模式来实现你想要做的事情(验证唯一的电子邮件地址作为过程的一部分):jerriepelser.com/blog/…

标签: c# post model fluentvalidation


【解决方案1】:

问题在于我试图在 POST 方法中影响模型,然后再为 Customer 模型调用 FluentValidation 验证器。尽管如此,我似乎可以更新模型,并在调试时在 IDE 中看到它更新,并将更新的值传递回视图,但没有发生更新。

我通过传递一个连接到我正在测试的电子邮件地址的随机字符串来测试这一点。 这证实了尽管看起来模型正在通过我的检查进行更新,但事实并非如此。呸。

为了解决这个问题,我在模型状态中添加了一个错误,在流畅验证之外:

public virtual ActionResult AddCustomer(CustomerAddViewModel model)
{            
    if (!string.IsNullOrEmpty(model.Email))
    {
      var exists = _userService.UserExists(model.Email);
      if (exists) 
      { 
        ModelState.AddModelError("Email", "Email Already Exists"); 
       }
    }
}

然后像往常一样使用 HTMl Helper 发布错误消息:

@Html.ValidationMessageFor(x => x.Email, "", new { @class = "help-block" })

我不明白为什么在执行验证之前我不能影响模型,但是在单步执行代码时仍然可以看到变化,这使得这比应该的要冗长得多。

【讨论】:

    猜你喜欢
    • 2016-03-09
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多