Alt*_*ept 7 validation asp.net-mvc
我有一个关于我在asp.net mvc中用于执行业务规则验证的方法的问题.
目前我有一个看起来像这样的异常类
public class ValidationException : Exception
{
private ModelStateDictionary State { get; set; }
public ValidationException(ModelStateDictionary state)
{
State = state;
}
public void MergeModelStates(ModelStateDictionary state)
{
state.Merge(this.State);
}
}
Run Code Online (Sandbox Code Playgroud)
和一个看起来像这样的验证器
public void Validate(IEntity entity)
{
ModelStateDictionary state = new ModelStateDictionary();
if (entity.Contact != null && _service.GetBy(entity.Contact.Id) == null)
state.AddModelError("Contact", "Invalid Contact.");
if (entity.Title.Length > 8)
state.AddModelError("title", "Title is too long...");
... etc
if (!state.IsValid)
throw new ValidationException(state);
}
Run Code Online (Sandbox Code Playgroud)
和控制器做这样的事情
public ActionResult Add()
{
var entity = new InputModel;
try
{
TryUpdateMode(inputModel);
..... Send input to a Repository (Repository calls Validate(entity);
}
catch (ValidationException validationException)
{
validationException.MergeModelStates(this.ModelState);
TryUpdateModel(inputModel);
return View("Add",inputModel);
}
return View("List");
}
Run Code Online (Sandbox Code Playgroud)
使用异常来做这样的事情是错误的吗?有更好的方法的例子吗?我真的不想将验证添加到模型实体本身.我看到它完成的另一种方法是将Controllers ModelState注入到Repository层,但这对我来说似乎很草率.
谢谢你的帮助
Rya*_*ner 14
例外通常应该用于例外情况,而不是处理在程序正常执行期间经常发生的事情.这有很多很好的理由 - 这里有一些我经常遇到的问题:
我通常喜欢的一种方法是提供一个公共Validate方法,它返回一个错误列表(但从不抛出异常),然后是一个调用Validate()的Save方法,如果有任何错误则抛出异常.您可以将行为从"如果模型无效时抛出"切换为"如果代码在模型处于无效状态时尝试保存则抛出".
要解决以下关于Validate vs. Save中抛出的性能的评论 - 抛出Save()将与抛出Validate()具有完全相同的性能损失.然而,关键的区别在于,这应该永远不会发生 - 您正在防止使用您的类不正确的开发人员,而不是使用异常作为验证方法.正确编写,调用save方法的代码应如下所示:
ValidationResult result = obj.Validate();
if (result.IsValid) {
obj.Save();
} else {
// display errors to the user
}
Run Code Online (Sandbox Code Playgroud)
如果开发人员在保存之前忘记检查验证状态,则仅抛出异常.这样做的好处是既可以在不使用异常的情况下进行验证,也可以通过永不允许保存无效实体来保护数据库.理想情况下,您根本不会在控制器中捕获异常并让一般错误处理例程处理它,因为问题不再是用户输入而是开发人员的错误.
归档时间: |
|
查看次数: |
4694 次 |
最近记录: |