我正在尝试验证用户输入,特别是用户密码。我有一些jQuery验证,但当然我还需要在服务器端验证。现在我的请求进入控制器,控制器将其移交给UserService
。一切都松散耦合,所以控制器真的不太了解内部UserService
。现在假设用户输入了一个弱密码,所以我需要告诉他“嘿,这是不够的。”
问题是:最好的方法是什么?
不知何故,我需要能够打电话
ModelState.AddModelError(field, exception);
为了表明出了什么问题,在哪里以及为什么 - 在简单的例子中我已经知道它是密码,因为它确实是表单上的唯一字段,但一般情况下这并不容易。现在我接近编写自己的Exception
类型来执行类似
ModelState.AddModelError(ex.Field, ex.Message);
,我可能需要一些额外的映射 - 这是NerdDinner在RuleViolations
中所采用的路径的必要条件。
但是,在NerdDinner中,业务对象是自我验证的。在这种情况下,这似乎不是最好的方法,因为这里的“业务对象”实际上只是用于实现IIdentity
的电子邮件和密码的存储。它不应该知道密码长度,应该可以在不同的应用程序中重用。
此外,ArgumentException
和ValidationException
似乎也不合适,因为第一个是违反合同,后者是DataAnnotations
使用。
所有这些当然只是冰山一角,因为潜伏着许多细微之处。也许有人可以指出我正确的方向?
答案 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。如果您关注的话,他们可以单独定义对象外部的验证逻辑。