2010-08-03 44 views
1

对我来说似乎是这样的,因为几乎所有向控制器发出的路由请求的下游抛出的异常都会抛入控制器或控制器的下游。控制器除了视图之外没有任何上游,这仅仅是控制器中发生的情况的呈现。MVC控制器层是错误处理的理想场所吗?

+0

但是如果视图中有一些错误呢? – 2010-08-03 11:44:38

+3

@ajay - 那么你做错了。你不应该在只显示数据的东西上遇到HTTP 500。所有逻辑,数据连接,模型绑定等应该在控制器/模型中发生,而不是在视图中。 – Tommy 2010-08-03 11:52:18

+1

@Tommy不是真的,这个视图当然只是显示数据,但是它可以访问模型,通常这不仅仅是一个简单的数据容器,因此可能会导致抛出异常。所以不要假设你的视图不会抛出异常。 – Mendelt 2010-08-03 12:05:50

回答

2

控制器操作是大多数错误处理的理想场所,但不是全部。

直到控制器操作完成执行后才会呈现视图。因此,例如,如果将视图传递给不仅仅是简单数据容器的视图模型,而且在呈现视图时引发异常(并非罕见情况)。在控制器操作中你无法理解这一点。

这里是一个工具,你可以用它来捕捉控制器 http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx

+0

已经从开始就使用Elmah :-) – ProfK 2010-08-03 13:06:45

1

它通常通过查看你需要显示在较低的水平如出现这样的错误控制器确定外例外BLL/DAL,仍然可以进行错误处理并且可以由控制器辅助,例如,

public ActionResult DisplayObject(int id) 
{ 
    // high level error handling 
    using (MyRepo repo = new MyRepo()) 
    { 
     var obj = repo.GetObj(id); 
     if (obj == null) 
      return View("ErrorDisplayingObject"); 
     else 
      return View("ObjectDetails"); 
    } 
} 
... 

public ActionResult SaveObject(int id, string param1, string param2) 
{ 
    // high level error handling 
    using (MyRepo repo = new MyRepo()) 
    { 
     var obj = repo.GetObj(id); 
     if (obj != null) 
     { 
      obj1.Param1 = param1; 
      obj2.Param2 = param2; 
      if (repo.Save()) 
       return View("SaveConfirmation"); 
     }   
    } 
    return View("ErrorSavingObject"); 
} 

... 
public class MyRepo 
{ 
    public MyObject GetObj(int id) 
    { 
     // low level error handling 
     try 
     { 
      // retrieve object 

     } 
     catch (Exception) 
     { 
      return null; 
     } 
    } 

    public bool Save() 
    { 
     // low level error handling 
     try 
     { 
      // save data 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 
} 
+0

我完全同意这种较低级别的错误处理,只是不像你这样做。如果某些东西不能保存,为什么返回false?为什么不让这个例外冒出来呢? – ProfK 2010-08-03 12:28:49

+0

@ProfK:你的确可以让它起泡,上面只是你可以做到的很多方法的一个例子:)个人...我会一直让异常冒出来,因为你想知道*完全*为什么它从来没有保存,甚至在视图本身输出。 – James 2010-08-03 13:04:22

1

模型必须是您可以进行验证的最合适的地方。理想情况下,模型必须是域模型应该放置的地方。因此,这使得它成为错误验证的理想场所。

+0

为模型欢呼。控制者应该是精益和平均的。模型应该很胖。实际上,我将验证和数据访问分解为服务和存储库层。但是 - 这是模型验证的良好开端,http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx – gnome 2010-08-03 14:04:14

1

它取决于异常和您的操作。例如,如果您保存的实体可能会破坏某些业务规则,那么预计您的BLL会抛出一个异常(例如BusinessRuleXXException)来表示这种不合规情况。在这种情况下,您必须处理该异常(控制器是做这件事的好地方),并向用户显示一条适当的消息,指出 出了什么问题(由于bla bla ...,您不能保存这个消息)。

在另一方面,你可能在至极 you're执行某些动作的越野车应用程序,你挑起的错误,例如像被违反了PK约束或许外部 服务不可用或任何其他情形那些预计不会在您的应用程序中代表真正的例外。对于这种类型的错误,我的建议是通过使用HandleError过滤器或自定义过滤器来处理全局错误,并处理错误 并记录它们,并将用户重定向到错误页面,其中有一个友好的“对不起,出错了。已经派出一支训练有素的猴子来处理这种情况,“信息显示。

问候。