前言
看的是入门视频,就希望培养一个学习的习惯吧。
前段时间看了微软的SurfaceBook的视频,被惊艳到了,但是我没钱买啊。。。
第17集 WCF中未经处理的异常 Unhandled exceptions in WCF
这集讲一下WCF中服务端如果出现异常会怎么样。还是用上集的demo。
服务端代码:
public class CalculatorService : ICalculatorService { public double Divide(int numerator, int denominator) { return numerator / denominator; } }
一个简单的除法,不考虑除0的情况,所以在客户端传入除数0来引发异常。
首先修改服务端的app.config 配置文件,先使用basicHttpBinding
<endpoint address="" binding="basicHttpBinding" contract="CalculatorService.ICalculatorService">
然后把这个service host起来。
新建一个Winform客户端作为测试Client,界面如下:
输入20 和 5 点击计算,得到4.
代码也很简单:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } ICalculatorService client = null; private void Form1_Load(object sender, EventArgs e) { client = new CalculatorServiceClient(); } private void btnCalc_Click(object sender, EventArgs e) { try { int num = int.Parse(tbNumerator.Text.Trim()), denominator = int.Parse(tbDenominator.Text.Trim()); lbRst.Text = client.Divide(num, denominator).ToString(); } catch(Exception ex) { lbRst.Text = ex.Message; } } }
定义一个变量client,在form load的时候实例化,然后在点击计算按钮的时候计算结果,在label上显示结果。
下面我们试验一下除0的情况:
得到除0异常提示。
再试验20/5的情况:
如图,我们依旧能得到想要的结果。
下面我们来试验一下使用wsHttpBinding
先改配置文件的endpoint节点
<endpoint address="" binding="wsHttpBinding" contract="CalculatorService.ICalculatorService">
然后在wsHttpBinding中启用reliableSession
<wsHttpBinding > <binding> <security mode ="None"/> <reliableSession enabled ="true"/> </binding> </wsHttpBinding>
host起来,然后更新服务端的服务引用,可以看到如下:
<endpoint address="http://localhost:8080/" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculatorService" contract="CalculatorSerivce.ICalculatorService" name="WSHttpBinding_ICalculatorService">
然后运行client,先试验一下正常的情况:
结果正常。
再来试验一下除0的情况:
得到异常提示。
再试验正常的情况,得到一个异常:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
现在,无论除数是否为0,都无法再得到结果。
究其原因,是因为我们在wsHttpBinding中启用了reliableSession,当服务端有未经处理异常时,就会破坏传输的channel,使之进入Faulted 状态。
如果没有启动reliableSession,结果就和basicHttpBinding 一样。
最基本的解决方法就是要重新实例化一个ServiceClient。
client = new CalculatorServiceClient();
然后就能重新调用了。
但是在实际的生产环境中,肯定不能在所有地方都加上这么一个new。下一集我们会学习一下如何把这个Exception转换城SoapFault(意思是要throw SoapFault Exception,而不要throw 普通的.net Exception),那样channel就不会被破坏了,session就可以保持了。
这集学习了不同Binding中WCF如何处理服务端的异常。
ThankYou!