MVC2:验证用户输入/最佳实践

时间:2010-03-09 22:30:19

标签: asp.net-mvc asp.net-mvc-2 validation

我正在尝试验证用户输入,特别是用户密码。我有一些jQuery验证,但当然我还需要在服务器端验证。现在我的请求进入控制器,控制器将其移交给UserService。一切都松散耦合,所以控制器真的不太了解内部UserService。现在假设用户输入了一个弱密码,所以我需要告诉他“嘿,这是不够的。”

问题是:最好的方法是什么?

不知何故,我需要能够打电话

ModelState.AddModelError(field, exception);

为了表明出了什么问题,在哪里以及为什么 - 在简单的例子中我已经知道它是密码,因为它确实是表单上的唯一字段,但一般情况下这并不容易。现在我接近编写自己的Exception类型来执行类似

的操作

ModelState.AddModelError(ex.Field, ex.Message);,我可能需要一些额外的映射 - 这是NerdDinner在RuleViolations中所采用的路径的必要条件。

但是,在NerdDinner中,业务对象是自我验证的。在这种情况下,这似乎不是最好的方法,因为这里的“业务对象”实际上只是用于实现IIdentity的电子邮件和密码的存储。它不应该知道密码长度,应该可以在不同的应用程序中重用。

此外,ArgumentExceptionValidationException似乎也不合适,因为第一个是违反合同,后者是DataAnnotations使用。

所有这些当然只是冰山一角,因为潜伏着许多细微之处。也许有人可以指出我正确的方向?

2 个答案:

答案 0 :(得分:1)

您可以使用xVal

答案 1 :(得分:1)

如果我理解正确,您需要验证用户密码是否足够或不足。如果您没有对对象本身使用自我验证,那么我可以建议您在用户服务上使用验证方法。

...
var result = userService.Validate(newUser);
if (!result.IsValid) {    
    result.Errors.ForEach( m => ModelState.AddModelError(m.field, m.message));
}
...

那怎么样?

这种方法的唯一问题是,要访问User对象周围的任何验证,您必须将其传递给userService,这可能是您想要做的,也可能不是。

回答下面的评论:

那么你必须创建一个ValidationResult,比如。

public class ValidationResult
{
   public string Field {get;set;}
   public string Message {get;set;}
}

因此,如果我正确阅读,您的Controller有一个UserService,UserService有一个Validator,Validator验证用户。

当您将此验证从Validator传递到UserService到Controller时,只需拦截并使用它,然后传递它。

如果您不想为自己的验证库(您不应该)发挥作用,那么有一些很棒的工具,如Enterprise Library和FluentValidation。如果您关注的话,他们可以单独定义对象外部的验证逻辑。