【问题标题】:Validation using attributes使用属性验证
【发布时间】:2011-12-17 02:55:42
【问题描述】:

比方说,我有一个简单的类:

public class User
{
  [Required(AllowEmptyStrings = false, ErrorMessage="EmailIsRequired"]
  public string EmailAddress { get; set; }
}

我知道如何在 System.ComponentModel.DataAnnotations 命名空间中使用 Validator.TryValidateProperty 和 Validator.TryValidateObject。为了使其工作,您需要一个要验证的对象的实际实例。

但是现在,我想在没有 User 类实例的情况下验证某个值,例如:

TryValidateValue(typeof(User), "EmailAddress", "test@test.com");

目标是我想在实际实例化对象本身之前测试一个值(原因是我只允许创建有效的域实体)。所以实际上我想在类而不是实例上使用验证属性。

有什么想法可以做到吗?

谢谢!

编辑:同时我决定不使用数据注释,而是使用http://fluentvalidation.codeplex.com,以便将验证移到实体之外。这种方式可以从实体以及我的命令处理程序中触发验证。由于流利的符号,验证本身看起来也更具可读性。

【问题讨论】:

  • 您提到如果域对象无效,您会尝试避免实例化它们,但是实例化它有什么影响?有可能你的对象做了太多的事情,如果简单地调用构造函数就会搞砸,你应该拆分它的职责。
  • 域实体正在检查其构造函数中的所有字段,如果其中任何一个未验证,则抛出异常,因此无法创建对象。但是现在,在我的命令处理程序中,为了进行上下文验证,我需要验证电子邮件地址,但我不需要对象本身。所以我想知道:为什么我不能在不需要这个对象的实例的情况下重用这个电子邮件验证。我也可以完全从实体中删除验证,但是我猜我不能使用数据注释......
  • 有没有办法创建自定义派生注释?然后,您可以在注释之间共享验证的实现,并为此命令处理程序。那将是一种 hack,但我个人认为注释不是域约束验证的完整或完美分解的架构解决方案(它们无法处理跨属性约束,并且如果应用于类,则不支持丰富的逻辑),所以你只会用你所拥有的做最好的。
  • 是的,我当然只会将它们用于简单的验证逻辑。我相信交叉属性验证也是可能的(但还没有开箱即用)......

标签: c# asp.net-mvc-3 validation domain-driven-design data-annotations


【解决方案1】:

这是一个如何使用TryValidateValue 方法的示例:

public class User
{
    [Required(AllowEmptyStrings = false, ErrorMessage = "EmailIsRequired")]
    public string EmailAddress { get; set; }
}

class Program
{
    static void Main()
    {
        var value = "test@test.com";

        var context = new ValidationContext(value, null, null);        
        var results = new List<ValidationResult>();
        var attributes = typeof(User)
            .GetProperty("EmailAddress")
            .GetCustomAttributes(false)
            .OfType<ValidationAttribute>()
            .ToArray();

        if (!Validator.TryValidateValue(value, context, results, attributes))
        {
            foreach (var result in results)
            {
                Console.WriteLine(result.ErrorMessage);
            }
        }
        else
        {
            Console.WriteLine("{0} is valid", value);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 2021-05-15
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多