类/模型级别验证(而不是属性级别)? (ASP.NET MVC 2.0)级别、而不是、属性、模型

2023-09-02 23:54:14 作者:不羁.

基本上,标题说什么。我有几个属性结合在一起,真正做一个符合逻辑的答案,我想运行一个服务器端验证code(我写的),它把这些多个领域考虑在内,并挂接到只有一个验证输出/错误消息,用户在网页上见

我看着斯科特guthries扩展属性,并在您的DataAnnotations声明使用它的方法,但是,我所看到的,有没有办法来声明对多个属性的DataAnnotations-style属性,你只能将声明(例如:[邮件],[范围],[必填])在一个属性:(

我在默认的MVC当你开始一个新项目出现2.0项目看了看PropertiesMustMatchAttribute,这个例子是为使用一对销来检查你的机油是有用的 - !没有用

我已经尝试过这种方法,但是,创建一个类级别的属性,并且不知道如何在我的aspx页面显示此错误。我曾试图html.ValidationMessage(ClassNameWhereAttributeIsAdded),以及各种其他的事情,到现在也没有工作。我应该提到,没有做验证在这个级别ONE的博客文章 - 尽管这是一个共同的需要在任何项目或业务逻辑场景

谁能帮助我有我的消息显示在我的aspx页面,并且如果可能的一个适当的文档或引用解释在这个级别的验证?

解决方案

现在,您已经了解了数据注解和到达它们不适合您的方案,我建议你在看的 FluentValidation ,它的integration在ASP.NET MVC 和方式将unit测试你的验证逻辑 - 你会不会失望(我真的什么都没有对数据的注解,他们是伟大的博客文章和教程,但一旦你面对现实世界的应用程序,您快速实现的限制)

更新:

按照要求在评论部分下面是一个使用FluentValidation框架与一个服务器端验证函数访问多个属性(请不要这样做,因为它是丑陋的,有一个更好的方式)的例子:

 类AUTHINFO
{
    公共字符串的用户名{获得;组; }
    公共字符串密码{获得;组; }
    公共字符串ConfirmPassword {获得;组; }
}

类AuthInfoValidator:AbstractValidator< AUTHINFO>
{
    公众覆盖的ValidationResult验证(AUTHINFO实例)
    {
        VAR的结果= base.Validate(实例);
        如果(string.IsNullOrEmpty(instance.Username))
        {
            result.Errors.Add(新ValidationFailure(用户名,用户名要求));
        }
        如果(string.IsNullOrEmpty(instance.Password))
        {
            result.Errors.Add(新ValidationFailure(密码,需要密码));
        }
        如果(string.IsNullOrEmpty(instance.ConfirmPassword))
        {
            result.Errors.Add(新ValidationFailure(ConfirmPassword,ConfirmPassword需要));
        }
        如果(instance.Password!= instance.ConfirmPassword)
        {
            result.Errors.Add(新ValidationFailure(ConfirmPassword,密码必须匹配));
        }
        返回结果;
    }
}
 

更自然的方式做,这是下面的(它也不会受到财产重新命名,因为它包含没有神奇的字符串):

 类AuthInfoValidator:AbstractValidator< AUTHINFO>
{
    公共AuthInfoValidator()
    {
        RuleFor(X => x.Username)
            .NotEmpty()
            .WithMessage(用户名要求);

        RuleFor(X => x.Password)
            .NotEmpty()
            .WithMessage(需要密码);

        RuleFor(X => x.ConfirmPassword)
            .NotEmpty()
            .WithMessage(ConfirmPassword需要);

        RuleFor(X => x.ConfirmPassword)
            .Equal(X => x.Password)
            .WithMessage(密码必须匹配);
    }
}
 
详解ASP.NET MVC 中的 View 模型

Basically, what the title says. I have several properties that combine together to really make one logical answer, and i would like to run a server-side validation code (that i write) which take these multiple fields into account and hook up to only one validation output/error message that users see on the webpage.

I looked at scott guthries method of extending an attribute and using it in your dataannotations declarations, but, as i can see, there is no way to declare a dataannotations-style attribute on multiple properties, and you can only place the declarations (such as [Email], [Range], [Required]) over one property :(.

i have looked at the PropertiesMustMatchAttribute in the default mvc 2.0 project that appears when you start a new project, this example is as useful as using a pair of pins to check your motor oil - useless!

i have tried this method, however, creating a class level attribute, and have no idea how to display the error from this in my aspx page. i have tried html.ValidationMessage("ClassNameWhereAttributeIsAdded") and a variety of other things, and it has not worked. and i should mention, there is NOT ONE blog post on doing validation at this level - despite this being a common need in any project or business logic scenario!

can anyone help me in having my message displayed in my aspx page, and also if possible a proper document or reference explaining validation at this level?

解决方案

Now that you've looked at Data Annotations and arrived to the conclusion that they are not adapted to your scenario I would suggest you looking at FluentValidation, its integration with ASP.NET MVC and the way you would unit test your validation logic - you won't be disappointed (I really have nothing against Data annotations, they are great for blog posts and tutorials but once you are confronted to real world applications you quickly realize the limits).

UPDATE:

As requested in the comments section here's an example of using the FluentValidation framework with one server-side validation function accessing multiple properties (please don't do this as it is ugly and there's a better way):

class AuthInfo
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}

class AuthInfoValidator : AbstractValidator<AuthInfo>
{
    public override ValidationResult Validate(AuthInfo instance)
    {
        var result = base.Validate(instance);
        if (string.IsNullOrEmpty(instance.Username))
        {
            result.Errors.Add(new ValidationFailure("Username", "Username is required"));
        }
        if (string.IsNullOrEmpty(instance.Password))
        {
            result.Errors.Add(new ValidationFailure("Password", "Password is required"));
        }
        if (string.IsNullOrEmpty(instance.ConfirmPassword))
        {
            result.Errors.Add(new ValidationFailure("ConfirmPassword", "ConfirmPassword is required"));
        }
        if (instance.Password != instance.ConfirmPassword)
        {
            result.Errors.Add(new ValidationFailure("ConfirmPassword", "Passwords must match"));
        }
        return result;
    }
}

The more natural way to do this is the following (it is also immune to property rename as it contains no magic strings):

class AuthInfoValidator : AbstractValidator<AuthInfo>
{
    public AuthInfoValidator()
    {
        RuleFor(x => x.Username)
            .NotEmpty()
            .WithMessage("Username is required");

        RuleFor(x => x.Password)
            .NotEmpty()
            .WithMessage("Password is required");

        RuleFor(x => x.ConfirmPassword)
            .NotEmpty()
            .WithMessage("ConfirmPassword is required");

        RuleFor(x => x.ConfirmPassword)
            .Equal(x => x.Password)
            .WithMessage("Passwords must match");
    }
}