我想我在这里遗漏了一些基本的东西,但我已经挖掘了两个多小时,一定是忽略了显而易见的东西。如果是这样的话,我道歉。
我有一个MVC3站点,我有一个服务层供控制器与之通信,还有一个存储库供我的服务层与之通信(所有这些都是使用IoC容器解耦的,但这在这里是无关紧要的)。我的域模型是EF4实体,在控制器、服务和存储库之间共享。
我有一个用于注册的视图模型,如下所示:
public class SignupViewModel
{
[DisplayName("Email")]
[Required, RegularExpression(@"^.+@.+\..+$")]
public string Email { get; set; }
[DisplayName("Password")]
[Required]
public string Password { get; set; }
[DisplayName("Confirm password")]
[Required, Compare("Password")]
public string PasswordConfirmation { get; set; }
}我的用户域模型如下所示:
public class User
{
public int Id { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public string PasswordSalt { get; set; }
}我有一个用于注册用户的服务方法,如下所示:
public void Register(User user, string planTextPassword)
{
//Make sure the email address is not taken.
bool emailIsTaken = IsEmailTaken(user.Email);
if (emailIsTaken)
{
//What do I do here?
}
else
{
//Create the user.
}
}最后,我的控制器操作将它们联系在一起:
public ActionResult Signup(SignupViewModel signupViewModel)
{
if (ModelState.IsValid)
{
_accountService.Register(Mapper.Map<SignupViewModel, User>(signupViewModel), signupViewModel.Password);
_unitOfWork.Commit();
}
return View(signupViewModel);
}正如您在我的服务方法中的注释中所看到的,当服务级别验证失败时,我该怎么办?正如在this question中所讨论的,我不应该抛出异常。但我不确定我是否理解了Ryan的建议,或者这是否仍然适用(例如,现在有没有更好的方法来处理MVC3,或者现在可用的其他工具,比如Fluent Validation)。
就像我说的,我想在这一点上我不能只见树木不见森林,但在过去的两三个小时里,我试图自己解决这个问题,我想我可能会有更好的运气,只是问了一个问题。
提前谢谢。
发布于 2011-02-27 14:38:10
我曾经试过做Ryan所说的事情。他所说的基本上是你的服务应该是这样的:
public class TheService{
ValidationResult Validate(YourType item);
Save(YourType item);
}其用法是首先调用Validate,如果保存成功,则调用ValidationResult。Save将再次验证实体,以确保您没有忘记验证它。不同之处在于,如果在Save调用validate时出现错误,则会抛出异常。
就我个人而言,我已经这样做过一次,以后不会再这样做了。我认为只要抛出一个异常就可以让一切变得更清晰,并且只需要更少的代码来维护。
要将错误信息返回给控制器,您需要创建自己的异常。它可能看起来像这样:
public class RulesException : Exception{
public IEnumerable<ErrorInfo> Errors {get;set;}
}
public class ErrorInfo{
public string PropertyName {get;set;}
public string ErrorMessage {get;set;}
}沿着这些路线的一些东西是一个开始。要获得更好的实现,请查看xVal的源代码
注意:如果使用异常,请尽量避免在循环内执行try/catch时编写代码。当涉及到异常时,这是要避免的最重要的事情,因为它们更昂贵,但与数据库调用相比,例如,它是便宜的。
发布于 2011-02-27 14:29:50
如果您不想使用异常,那么除了让您的服务方法返回某种丰富的错误消息对象之外,您实际上别无选择。在链接的帖子中,我唯一强烈同意的观点是,异常(本身)不太可能产生好的错误消息。他们所做的事情是他们很难被忽视,所以你很可能意识到你有一个问题。
此外,无论如何您都必须处理异常,因为即使您在服务代码中完全避免了它们,您的代码也不是唯一可能导致抛出异常的东西。
也就是说,您可以返回一个可以表示成功或失败的类的实例,而不是让Register具有void返回类型,并且在失败的情况下有另一个列出错误的属性。这是一件有原则的事情--例如,在像Haskell这样的语言中这是很常见的。
https://stackoverflow.com/questions/5131745
复制相似问题