如何处理较新版本的 .NET(3.5 以上)中数据绑定期间发生的异常?
How to handle exceptions that occur during databinding in newer versions of .NET (above 3.5)?
我正在关注 MSDN 中的这个示例
Handle errors and exceptions that occur with databinding (same example also here)
这个例子背后的想法:
- TextBox 控件使用
BindingSource
和 Binding
对象绑定到业务对象属性。业务对象是模型。
- 业务对象中的 属性 setter 验证输入并在输入无效时抛出异常。
- 绑定对象配置为捕获此类异常。
- 绑定触发
BindingComplete
事件。如果有异常,它会被捕获,异常消息可通过 BindingCompleteEventArgs
获得。验证错误消息可以通过这种方式回溯到表示层。
到目前为止 - 很好。
这是奇怪的部分。不同版本的 .NET 对业务对象抛出的异常的捕获是不同的。
- 这适用于 .NET 3.5 版。绑定框架捕获异常。
BindingComplete
事件已触发。事件参数表明绑定不成功。不出所料。
- .NET 版本 4.0、4.5、4.5.2 不捕获模型 属性 setter 中的异常。执行因该异常而中断。
从微软的示例中复制粘贴的相同源代码。我只在项目属性中更改.NET 的版本。
- 较新版本的 .NET 中发生了什么变化,以至于此示例无法按预期运行?
- 有没有办法让它在较新版本的 .NET 上工作?该示例是否缺少在较新版本的 .NET 中引入的设置?
附录 A:相关阅读和现有技术
在此较早的线程中也提出了类似的方法:Data Binding and throwing exception in setter (2009)
A thread on MSDN forum (2010) 建议在 Binding.Parse
事件中抛出异常。
[奇怪的是,即使在 Control.Validating 事件处理程序中将 e.Cancel
设置为 true
,也会发生数据绑定。这是一项功能吗?]
附录 B:对预期评论的先发制人的回应
Using exceptions for user input validation isn't great.
我同意。同时,模型中的 属性 setter 必须验证参数并在参数为垃圾时抛出异常。不能有接受无效参数的模型。
话虽如此,我也对其他想法持开放态度。模型是否有其他方式进行输入验证并将验证错误信息发送到演示文稿?
That example is WinForms. Why don't you use WPF?
由于遗留问题,我正在使用 WinForms。
这似乎是 .Net 3.5 和 .Net 4+ 中被归类为 user-unhandled 异常的差异。 .Net 4.0 可能不会发生此更改,因为 .Net 4.5+ in-place 是 .Net 4 的替代品。
考虑在主题代码的 属性 setter 中抛出的 System.Exception
的以下配置。以下图像是从 VS2013 捕获的。 VS2015+ 使用不同的异常设置对话框(参见:The New Exception Settings Window in Visual Studio 2015)。要查看 user-unhandled 选项,您需要启用 "Just-My-Code" 调试。
针对 .Net 4.7 编译时,调试器将在抛出异常时中断。但是,针对 .Net 3.5 进行编译时,调试器不会在抛出异常时中断。
如果清除 "break when this exception type is user-unhandled" 框,您将获得与 3.5 相同的行为。如果您 运行 没有附加调试器,无论 .Net 版本如何,行为都是相同的。
我正在关注 MSDN 中的这个示例
Handle errors and exceptions that occur with databinding (same example also here)
这个例子背后的想法:
- TextBox 控件使用
BindingSource
和Binding
对象绑定到业务对象属性。业务对象是模型。 - 业务对象中的 属性 setter 验证输入并在输入无效时抛出异常。
- 绑定对象配置为捕获此类异常。
- 绑定触发
BindingComplete
事件。如果有异常,它会被捕获,异常消息可通过BindingCompleteEventArgs
获得。验证错误消息可以通过这种方式回溯到表示层。
到目前为止 - 很好。
这是奇怪的部分。不同版本的 .NET 对业务对象抛出的异常的捕获是不同的。
- 这适用于 .NET 3.5 版。绑定框架捕获异常。
BindingComplete
事件已触发。事件参数表明绑定不成功。不出所料。 - .NET 版本 4.0、4.5、4.5.2 不捕获模型 属性 setter 中的异常。执行因该异常而中断。
从微软的示例中复制粘贴的相同源代码。我只在项目属性中更改.NET 的版本。
- 较新版本的 .NET 中发生了什么变化,以至于此示例无法按预期运行?
- 有没有办法让它在较新版本的 .NET 上工作?该示例是否缺少在较新版本的 .NET 中引入的设置?
附录 A:相关阅读和现有技术
在此较早的线程中也提出了类似的方法:Data Binding and throwing exception in setter (2009)
A thread on MSDN forum (2010) 建议在 Binding.Parse
事件中抛出异常。
[奇怪的是,即使在 Control.Validating 事件处理程序中将 e.Cancel
设置为 true
,也会发生数据绑定。这是一项功能吗?]
附录 B:对预期评论的先发制人的回应
Using exceptions for user input validation isn't great.
我同意。同时,模型中的 属性 setter 必须验证参数并在参数为垃圾时抛出异常。不能有接受无效参数的模型。
话虽如此,我也对其他想法持开放态度。模型是否有其他方式进行输入验证并将验证错误信息发送到演示文稿?
That example is WinForms. Why don't you use WPF?
由于遗留问题,我正在使用 WinForms。
这似乎是 .Net 3.5 和 .Net 4+ 中被归类为 user-unhandled 异常的差异。 .Net 4.0 可能不会发生此更改,因为 .Net 4.5+ in-place 是 .Net 4 的替代品。
考虑在主题代码的 属性 setter 中抛出的 System.Exception
的以下配置。以下图像是从 VS2013 捕获的。 VS2015+ 使用不同的异常设置对话框(参见:The New Exception Settings Window in Visual Studio 2015)。要查看 user-unhandled 选项,您需要启用 "Just-My-Code" 调试。
针对 .Net 4.7 编译时,调试器将在抛出异常时中断。但是,针对 .Net 3.5 进行编译时,调试器不会在抛出异常时中断。
如果清除 "break when this exception type is user-unhandled" 框,您将获得与 3.5 相同的行为。如果您 运行 没有附加调试器,无论 .Net 版本如何,行为都是相同的。