我在哪里捕获 MVVM 中的异常?
Posted
技术标签:
【中文标题】我在哪里捕获 MVVM 中的异常?【英文标题】:Where do I catch Exceptions in MVVM? 【发布时间】:2011-05-12 19:47:51 【问题描述】:我的视图模型类有一个连接到服务的方法(不确定这是否是好的做法,或者视图模型是否应该是严格的属性和属性更改机制)。当然,我想在连接或断开连接时处理任何可能的 WCF 异常。
考虑到这是一个我想引起用户注意的异常,让我们以未找到的端点为例。考虑粗略的代码示例:
public void Connect()
ServiceClient proxy = null;
try
proxy = new ServiceClient();
proxy.Subscribe();
// ...
catch(EndpointNotFoundException)
// should I do something here?
// .. other WCF related exception catches and a finally
直接在 catch 中调用 System.Windows.MessageBox.Show() 是否被认为是一种好习惯,或者我应该重新抛出异常以便我的 WPF 应用程序的另一层捕获它?如果是这样,捕获此类异常的理想位置在哪里?
【问题讨论】:
我以这种方式处理 WCF 错误:MSDN 您是否有任何其他可能适合 MVVM 模式或 WPF 的链接,因为我正在使用它们?我不确定 Silverlight(我从未编写过 silverlight 应用程序)是否适合我的场景。我更感兴趣的是在哪里捕获模式中的异常。 用户究竟打算如何处理这个异常?您应该告诉用户他需要什么才能正确“处理”这个异常。如果用户对此无能为力,则不要告诉用户任何异常,也许是“对不起,但出了点问题”。 这可能会有所帮助...blogs.microsoft.co.il/blogs/zuker/archive/2009/03/23/… @John,用户不需要拯救世界。我只需要向用户展示远端不可用。这就是我提到 MessageBox 的原因。这个问题不是关于我应该告诉用户什么,我想知道如何优雅地处理我正在使用的模式中的异常。 【参考方案1】:我一直在处理我的 MVVM 客户端中的异常,方法是捕获它们并将它们包装在 ErrorViewModel
属性中,无论 ViewModel
捕获了异常。
假设 ViewModel A 捕获了 EndpointNotFoundException。为了呈现这个错误,我将异常包装在一个 ErrorViewModel 中并将其分配给 A 的 Error 属性。
与 A 关联的视图包含绑定到 A 的错误属性的 ContentControl
。同时,我使用DataTemplate
将错误视图关联到错误视图模型。在该视图中,Visibility
取决于 A 的 Error 属性是否包含异常。
所以 A 的 View 包含一个错误消息 View,它只会在捕获到异常时出现,并且可以被用户关闭(错误消息 View 上的 OK 按钮会调用A 上的命令清除 A 的 Error 属性,从而将错误消息视图的可见性更改为 Collapsed
)。
到目前为止,这似乎是一种保留正确 MVVM 解耦的好方法。
希望对您有所帮助。老实说,无论如何,我认为 WPF 应用程序中的System.Windows.MessageBox.Show()
纯粹是最后的手段。为什么要放弃对 UI 的丰富控制权而转而使用那个旧东西?说到这里,这里是another popup-implementation approach。
【讨论】:
我认为 MessageBox 将是最后的手段(并且暗中希望如此)。 我喜欢这种方法; ViewModel 的工作是表示可以可视化的状态。因此,模型中某处发生的错误不应该被“推送”到视图;相反,ViewModel 的状态应该反映存在错误。我还可以看到将错误传播到某个 ErrorDisplayService,并使用一种集中机制来暴露来自各种来源的错误状态。 我非常喜欢这个。如果我理解你,你会将任何意味着“我无法到达另一端”的异常抽象为一些错误,以显示给用户。那很完美。如果这是一个 API,我会建议将此类异常包装在另一个说“无法到达另一端”的地方。 这个解决方案很漂亮。谢谢 djacobson! @Dan Bryant 我见过一些人提到类似 ErrorDisplayService 的东西,或其他中介模式的实现(错误呈现者订阅接收错误通知,而错误处理程序订阅处理错误) 在这种情况下。我正在从事的项目目前足够小,我已经能够避免深入,但我喜欢这个想法。 :)以上是关于我在哪里捕获 MVVM 中的异常?的主要内容,如果未能解决你的问题,请参考以下文章
Spring MongoRepository,在哪里捕获异常?