C# 使用属性进行验证

C# 使用属性进行验证,c#,asp.net-mvc-3,validation,domain-driven-design,data-annotations,C#,Asp.net Mvc 3,Validation,Domain Driven Design,Data Annotations,比如说,我有一个简单的课程: public class User { [Required(AllowEmptyStrings = false, ErrorMessage="EmailIsRequired"] public string EmailAddress { get; set; } } 我知道如何在System.ComponentModel.DataAnnotations命名空间中使用Validator.TryValidateProperty和Validator.TryValid

比如说,我有一个简单的课程:

public class User
{
  [Required(AllowEmptyStrings = false, ErrorMessage="EmailIsRequired"]
  public string EmailAddress { get; set; }
}
我知道如何在System.ComponentModel.DataAnnotations命名空间中使用Validator.TryValidateProperty和Validator.TryValidateObject。为了使其工作,您需要要验证的对象的实际实例

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

TryValidateValue(typeof(User), "EmailAddress", "test@test.com");
目标是在实际必须实例化对象本身之前测试一个值(原因是我只允许创建有效的域实体)。所以事实上,我想在类上使用验证属性,而不是实例

你知道怎么做吗

谢谢


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

下面是一个如何使用该方法的示例:

公共类用户
{
[必需(AllowEmptyStrings=false,ErrorMessage=“EmailIsRequired”)]
公共字符串电子邮件地址{get;set;}
}
班级计划
{
静态void Main()
{
变量值=”test@test.com";
var context=newvalidationcontext(值,null,null);
var results=新列表();
var attributes=typeof(用户)
.GetProperty(“电子邮件地址”)
.GetCustomAttributes(false)
第()类
.ToArray();
if(!Validator.TryValidateValue(值、上下文、结果、属性))
{
foreach(结果中的var结果)
{
Console.WriteLine(result.ErrorMessage);
}
}
其他的
{
WriteLine(“{0}有效”,值);
}
}
}

您提到,如果域对象无效,您会试图避免实例化它们,但是实例化它会产生什么影响?可能是您的对象做了太多的事情,如果简单地调用构造函数会搞乱任何事情,您应该将其职责分开。域实体正在检查其构造函数中的所有字段,如果其中任何字段未验证,将引发异常,因此无法创建对象。但是现在,在我的命令处理程序中,对于上下文验证,我需要验证电子邮件地址,但不需要对象本身。所以我想知道:为什么我不需要这个对象的实例就不能重用这个电子邮件验证呢。我也可以将验证完全从实体中移除,但我想我不能使用数据注释……有没有办法创建自定义的派生注释?然后,您可以在注释之间共享验证的实现,并为此命令处理程序共享验证。这可能是一种黑客行为,但我个人认为注释并不是域约束验证的完整或完美的体系结构解决方案(它们不能处理跨属性约束,如果应用于类,则不支持丰富的逻辑),因此您只能利用现有的做得最好。是的,当然,我只会将它们用于简单的验证逻辑。我相信跨属性验证也是可能的(但还不是现成的)。。。
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);
        }
    }
}