我有一个MVC EF5设置,有类:
Program
- 这是控制器UserInterface
- 这是视图,负责显示和提示数据。DataAccess
- 模型,这可以在我的EF模型类中创建,读取,更新和删除数据当DataAccess类尝试对我的数据库执行CRUD操作时,如果它捕获错误,则需要处理它,我的UserInterface类需要向用户打印消息,如果需要则报告任何错误。因此,当发生错误时,它需要先通过程序类,然后再通过UserInterface类,因为数据层不应直接与表示层通信。
有人建议我不要将异常传递给函数或将其返回给调用函数,但是我应该“向上面的层添加一个更简单的新例外”。所有关于异常的讨论都让我感到困惑,因为我对异常的体验仅限于这种格式:
try
{
// stuff
}
catch (exception ex)
{
console.writeline(ex.ToString());
}
我已经做了一些自己的研究,试图找到这个问题的答案,我已经学到了一些东西,但不知道如何把它们放在一起:
我了解到:
throw;
重新抛出异常并保留堆栈跟踪throw ex
抛出一个现有的异常,例如catch块中捕获的异常。并重置堆栈跟踪。但是,我不知道在哪里放置我的try / catch块以利用重新抛出
是否类似于以下代码?或者我错过了关于它是如何工作的观点?
编辑:(增加了一点,以便对其他人的猜测有所了解)
void MethodA()
{
try
{
MethodB();
}
catch (MyExceptionType ex)
{
// Do stuff appropriate for MyExceptionType
throw;
}
}
void MethodB()
{
try
{
MethodC();
}
catch (AnotherExceptionType ex)
{
// Do stuff appropriate for AnotherExceptionType
throw;
}
}
void MethodC()
{
try
{
// Do Stuff
}
catch (YetAnotherExceptionType ex)
{
// Do stuff appropriate for YetAnotherExceptionType
throw;
}
}
答案 0 :(得分:2)
不仅仅是如何使用不同类型的异常处理。在功能上你应该定义哪些层必须做什么,但有例外。
like data layer =>除了DataException或SQLException之外,不要抛出任何东西。记录它们并将通用数据库异常返回给UI。
业务层=>记录并重新抛出简单的业务异常 UI图层=>仅捕获业务异常并在业务异常内的消息中提醒它
一旦定义了所有这些,您就可以使用您学到的和总结的内容来构建它。
答案 1 :(得分:2)
通过抛出一个新的更简单的异常建议您做什么(我认为)是您将较低层的异常转换为新的,更高级别的异常,以便在外层使用。较低级别的例外情况不适合在该计划的高层消费。
例如,在LINQ to Entities中,当序列没有元素时,方法Single()
将抛出InvalidOperationException
。但是,此异常类型非常常见,因此很难在用户界面级别中捕获它:如何区分抛出此异常的不同可能性(例如,修改只读集合)?解决方案是将转换异常转换为应用程序可以轻松处理的另一种(新的,用户定义的)类型。
这是一个简单的例子:
public class MyUserService {
public User GetById(int id) {
try {
using(var ctx = new ModelContainer()) {
return ctx.Where(u => u.Id == id).Single();
}
}
catch(InvalidOperationException) {
// OOPs, there is no user with the given id!
throw new UserNotFoundException(id);
}
}
}
然后Program
层可以捕获UserNotFoundException并立即知道发生了什么,从而找到向用户解释错误的最佳方法。
细节将取决于程序的确切结构,但这样的东西可以在ASP.NET MVC应用程序中使用:
public class MyUserController : Controller {
private MyUserService Service = new MyUserService();
public ActionResult Details(int id) {
User user;
try {
user = Service.GetById(id);
}
catch(UserNotFoundException) {
// Oops, there is no such user. Return a 404 error
// Note that we do not care about the InvalidOperationException
// that was thrown inside GetById
return HttpNotFound("The user does not exist!");
}
// If we reach here we have a valid user
return View(user);
}
}