我有这种格式
asp.net MVC View -> 服务层 -> 存储库。
因此 View 调用服务层,其中包含业务/验证逻辑,后者又调用存储库。
现在我的服务层方法通常有一个 bool 返回类型,这样我就可以在数据库查询成功时返回 true。或者如果它失败了。然后向用户显示一条通用消息。
我当然会用 elmah 记录错误。但是我不确定我应该如何做到这一点。
像现在一样,我的存储库有用于更新、创建、删除的 void 返回类型。
也就是说,如果更新失败,我是否应该在我的存储库中有一个 try/catch 来抛出错误,然后我的服务层会捕获它并发出 elmah 信号并返回 false?
或者我应该让这些存储库方法返回一个“bool”,尝试/捕获存储库中的错误,然后将“true”或“false”返回给服务层,然后服务层返回“true”或“false”观点?
异常处理仍然让我困惑如何处理错误以及何时抛出错误以及何时捕获错误。
最佳答案
我一直使用的经验法则是:
- 在低级别,当操作由于异常情况而无法完成时抛出。
- 在中间层,捕获多个异常类型并重新包装为一个异常类型。
- 在最后负责的时刻处理异常。
- 文档!
这是一个多层 ASP.NET MVC 应用程序(UI、 Controller 、逻辑、安全、存储库)的伪代码示例:
- 用户点击提交按钮。
- 执行 Controller 操作并调用逻辑(业务)层。
- 逻辑方法使用当前用户凭据调用安全性
- 用户无效
- 安全层抛出SecurityException
- 逻辑层捕获,并用更通用的错误消息包装在 LogicException 中
- Controller 捕获 LogicException,重定向到错误页面。
- 用户有效且安全返回
- 用户无效
- 逻辑层调用存储库以完成操作
- 存储库失败
- 存储库抛出 RepositoryException
- 逻辑层捕获,并用更通用的错误消息包装在 LogicException 中
- Controller 捕获 LogicException,重定向到错误页面。
- 存储成功
- 存储库失败
- 逻辑层返回
- Controller 重定向到成功 View 。
注意,逻辑层只抛出一个异常类型——LogicException。任何冒泡的低级异常都被捕获,包装在一个新的 LogicException 实例中,然后被抛出。这给了我们很多优势。
首先,堆栈跟踪是可访问的。其次,调用者只需要处理一个异常类型而不是多个异常。第三,可以对技术异常消息进行处理以显示给用户,同时仍保留原始异常消息。最后,只有负责处理用户输入的代码才能真正了解用户的意图,并确定操作失败时的适当响应。 Repository 不知道 UI 是否应该显示错误页面或请求用户使用不同的值重试。 Controller 知道这一点。
顺便说一句,没有人说你不能这样做:
try
{
var result = DoSomethingOhMyWhatIsTheReturnType();
}
catch(LogicException e)
{
if(e.InnerException is SqlException)
{
// handle sql exceptions
}else if(e.InnerException is InvalidCastException)
{
// handle cast exceptions
}
// blah blah blah
}
关于c# - 错误处理 我应该抛出异常吗?还是源头处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1352359/