6

奖励赏金后更新

一个新的解决方案正在解决这个问题。请在此处参考 ASP.NET MVC 3 Preview 1:http ://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx

查看模型验证改进部分,您将在其中看到我的问题的解决方案。


原帖

参考我之前的文章如何使用 ASP.NET MVC 2 验证两个属性,我在其中询问如何比较两个属性以进行模型验证。

我确实发现答案很有用,但我遇到了一个完全不同的问题:

问题:如果 Property-level ValidationAttribute 包含错误,则 Class-level ValidationAttributes 不会被验证。

请考虑以下几点:

[EqualTo("Email", "EmailConfirm", ErrorMessage = "E-mailadresserne skal være ens")]
[EqualTo("Password", "PasswordConfirm", ErrorMessage = "Adgangskoderne skal være ens")]
[Bind(Exclude="UserId")]
public class EditSiteUser
{
    [Required(ErrorMessage="Du skal bekræfte adgangskode")]
    public string PasswordConfirm { get; set; }

    [Required(ErrorMessage="Du skal bekræfte e-mailadressen")]
    [Email(ErrorMessage="Ugyldig e-mailadresse")]
    public string EmailConfirm { get; set; }
    public int UserId { get; set; }

    [Required(ErrorMessage = "Du skal indtaste et brugernavn")]
    public string Username { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en adgangskode")]
    public string Password { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en e-mailadresse")]
    [Email(ErrorMessage = "Ugyldig e-mailadresse")]
    public string Email { get; set; }
}

这里我有两个类级别的属性来验证 EmailConfirm 和 PasswordConfirm。

如果像 Username 这样的字段为空,从而产生错误,则永远不会验证两个 EqualTo 属性。

有没有人有解决这个问题的建议?

编辑:如果您需要有关此问题的更多信息,请在评论中提问,我很乐意为您提供所需的任何其他信息。

问题:

问:“如果属性级别检查失败,为什么类级别检查得到验证很重要?”。

A:“因为这是表单的一部分,用户在表单中输入信息,然后通过 AJAX 回传。当表单返回时,它应该显示所有当前问题。”

问:“您在类中放置的 EqualTo 属性到底是什么?它是自定义验证属性吗?如果是,它是如何工作的?它有什么作用?”

A:EqualTo 是一个类级别的ValidationAttribute,它比较类实例的两个Properties 的值。查找“PropertiesMustMatchAttribute”以获得类似的实现。

4

3 回答 3

5

这不受支持。如果任何属性级别验证失败,则不执行类级别验证。我建议你看看MVC Foolproof Validation。它扩展了 MVC 验证以添加对条件属性验证的支持。我认为这将解决这个特殊情况的问题。

该项目站点声明它不适用于 MVC2 RC,因此您必须下载源代码并自己运行/采用他们的想法。

于 2010-06-28T18:06:46.140 回答
1

要扩展Scott Guthrie 文章IValidatableObject的链接,从 MVC 3 开始,您可以通过实现接口 来执行类级别验证。

这将在当前验证管道的上下文中工作,因此它可以嵌套在任意数量的自定义类和属性上,并继续返回可能的错误消息的完整数组。

对于你的类,放弃类级别的属性,并添加一个像这样调用的方法Validate

public class EditSiteUser : IValidatableObject
{
    public int UserId { get; set; }

    [Required(ErrorMessage = "Du skal indtaste et brugernavn")]
    public string Username { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en adgangskode")]
    public string Password { get; set; }

    [Required(ErrorMessage="Du skal bekræfte adgangskode")]
    public string PasswordConfirm { get; set; }

    [Required(ErrorMessage = "Du skal indtaste en e-mailadresse")]
    [Email(ErrorMessage = "Ugyldig e-mailadresse")]
    public string Email { get; set; }

    [Required(ErrorMessage="Du skal bekræfte e-mailadressen")]
    [Email(ErrorMessage="Ugyldig e-mailadresse")]
    public string EmailConfirm { get; set; }


    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    { 
      // put whatever class level validation you want here

      if (Email !== EmailConfirm)
      {
          yield return new ValidationResult("E-mailadresserne skal være ens", new[] {"EmailConfirm"})
      }

      if (Password !== PasswordConfirm)
      {
          yield return new ValidationResult("Adgangskoderne skal være ens", new[] {"PasswordConfirm"})
      }
    }

}

您可以根据需要继续发送yield return尽可能多的验证消息。

您可以将它们全部显示在客户端上@Html.ValidationSummary

如果您希望消息出现在特定控件旁边,则ValidationResult构造函数会使用受影响的属性进行重载,并且您可以使用HTML 帮助memberNames器为该特定属性提供验证消息,如下所示:ValidationMessageFor

@Html.ValidationMessageFor(Function(model) model.TestOne )

此外,值得一提的是,您可以使用CompareValidator轻松确保两个不同属性的值相等。使用此注解的好处是它会自动知道如何在客户端和服务器上强制执行此操作,而添加IValidatableObject只会在服务器上运行。

[DataType(DataType.Password)]
public string Password { get; set; }

[Compare("Password")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }

如需进一步阅读,请参阅 Scott Guthrie 的另一篇文章,其中包含有关类级别验证的更多详细信息。

于 2015-01-26T21:19:35.453 回答
0

从您的示例中,您希望有一个“确认其他输入框条目”框,正确的实现将是

 [EqualTo("Email", ErrorMessage = "E-mailadresserne skal være ens")]
 public string EmailConfirm { get; set; }

因为“错误”是对确认框的验证。或者换句话说,您希望在确认框旁边显示错误消息,说明它与电子邮件框中的不同。

这会将验证配置放回属性,并解决您的问题。

于 2010-07-05T14:29:46.477 回答