开发者社区> 行者武松> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

如何在调用WCF服务之前弹出一个确认对话框?

简介:
+关注继续查看

昨天有人在微博上问我如下一个问题:

老蒋,客户端调用wcf的一个接口函数时,有没有什么办法可以先弹出一个确认框,确认后再执行调用。因为这个接口函数再很多地方都执行了调用,所以我想在某个入口进行统一地弹出一个确认框...

20121007100122114.png

其实这个问题可以通过WCF的扩展来完成,具体来说这个扩展涉及到一个我们不太常用的组件“InteractiveChannelInitializer”,在我的《WCF全面解析》中对它有过概括性的介绍。InteractiveChannelInitializer实现了接口IInteractiveChannelInitializer,从名称可以看出这是一个“交互性”的“信道初始化器”,在一般情况下我们用它来动态地指定客户端调用凭证(比如在弹出的登录对话框中输入用户名和密码)。而上面这个问题就可以通过自定义InteractiveChannelInitializer来实现,我为此写了一个简单的实例(源代码从这里下载)。

右图所示的是实例的运行界面。我们以Windows Form应用的方式编写了一个“计算器”,计算结果通过调用WCF服务来获取。在每次调用服务之前都会弹出一个确认对话框,真正的服务调用只有在用户确认之后方能进行。

用于实现“服务调用确认”的自定义InteractiveChannelInitializer(InvocationConfirmationInteractiveChannelInitializer)定义如下。我们在BeginDisplayInitializationUI方法中弹出一个确认对话框,并将用户的确认选择封装到一个简单的AsyncResult对象中返回。在EndDisplayInitializationUI方法中,通过AsyncResult对象确认用户是否取消本次服务调用,如果是则抛出一个自定义的InvocationCancelException异常。

   1: public class InvocationConfirmationInteractiveChannelInitializer : IInteractiveChannelInitializer
   2: {
   3:     public const string ConfirmMessage = "程序执行过程涉及到WCF服务调用,是否继续?";
   4:     public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state)
   5:     {
   6:         bool cancel = MessageBox.Show(ConfirmMessage, "WCF服务调用确认", MessageBoxButtons.YesNo) == DialogResult.No;
   7:         return new SimpleAsynsResult(cancel);
   8:     }
   9:  
  10:     public void EndDisplayInitializationUI(IAsyncResult result)
  11:     {
  12:         SimpleAsynsResult asyncResult = (SimpleAsynsResult)result;
  13:         if((bool)asyncResult.AsyncState)
  14:         {
  15:             throw new InvocationCancelException("WCF服务调用被取消");
  16:         }
  17:     }
  18: }
  19:  
  20: public class SimpleAsynsResult:IAsyncResult
  21: {
  22:     public SimpleAsynsResult(object state)
  23:     {
  24:         this.AsyncState = state;
  25:     }
  26:  
  27:     public object AsyncState { get; private set; }
  28:     public WaitHandle AsyncWaitHandle { get; private set; }
  29:     public bool CompletedSynchronously
  30:     {
  31:         get { return true; }
  32:     }
  33:     public bool IsCompleted
  34:     {
  35:         get { return true; }
  36:     }
  37: }

我们通过一个自定义的ContractBehavior(InvocationConfirmationBehaviorAttribute )将上面自定义的InvocationConfirmationInteractiveChannelInitializer应用到客户端运行时。如下面的代码片断所示,在实现的ApplyClientBehavior方法中,我们创建了一个InvocationConfirmationInteractiveChannelInitializer对象并将其添加到客户端运行时的InteractiveChannelInitializers集合中。

   1: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
   2: public class InvocationConfirmationBehaviorAttribute : Attribute, IContractBehavior
   3: {
   4:     public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
   5:     public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
   6:     {
   7:         clientRuntime.InteractiveChannelInitializers.Add(new InvocationConfirmationInteractiveChannelInitializer());
   8:     }
   9:     public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { }
  10:     public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { }
  11: }

以特性形式定义的InvocationConfirmationBehaviorAttribute直接以如下的方式直接应用到作为服务契约的ICalcualtor接口中:

   1: [ServiceContract(Name = "CalculatorService", Namespace ="http://www.artech.com/")]
   2: 
   3: public interface ICalculator
   4: {
   5:     [OperationContract]
   6:     double Add(double x, double y);
   7: }

那么在进行服务调用的时候,确认对话框会自动弹出来。如果用户选择终止当前服务调用,那么InvocationCancelException异常会被抛出来,我们只需要捕捉该类型的异常即可。如下所示的是“=”按钮的Click事件代码:

   1: public partial class Form1 : Form
   2: {
   3:     //其他成员
   4:     private void buttonCalculate_Click(object sender, EventArgs e)
   5:     {
   6:         this.textBoxResult.Text = string.Empty;
   7:         using (ChannelFactory<ICalculator> channelfactory = new ChannelFactory<ICalculator>("calculatorservice"))
   8:         {
   9:             ICalculator calculator = channelfactory.CreateChannel();
  10:             try
  11:             {
  12:                 double op1 = double.Parse(this.textBoxOp1.Text);
  13:                 double op2 = double.Parse(this.textBoxOp2.Text);
  14:                 double result = calculator.Add(op1,op2);
  15:                 this.textBoxResult.Text = result.ToString();
  16:             }
  17:             catch (InvocationCancelException)
  18:             {
  19:             }
  20:             catch (Exception ex)
  21:             {
  22:                 MessageBox.Show(ex.Message);
  23:             }
  24:         }
  25:     }
  26: }

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
对话框和窗口的区别
“窗口”与“对话框”有什么区别?                       计算机类稿件的一大特点是文中的图很多。在这大量的图中,系统软件或应用软件的“界面”、“窗口”、“对话框”、“提示框”等的截图又占了很大的比例。
1648 0
C# WinForm登录窗口代码
Main窗体为应用程式主窗体,Login为登录窗体。均为SDI窗体。     两种实现方式如下:   1、应用程式入口放在Login窗体,在Login窗体实现登录机制,验证通过则创建Main窗体的实例,并将自身隐藏。
622 0
在控制台程序中隐藏控制台窗口!
大家都知道,当编写一个win32 console application时,当运行此类程序的时候默认情况下会有一个类似DOS窗口的console窗口,但是有的时候我们只想在程序中运行一段功能代码,不希望显示这个console窗口,让代码执行完毕之后程序自动退出.
613 0
【C大事】第二讲:对话框程序
<p><span style="font-size:14pt">选中图片控件,要点击边缘。</span><br><span style="font-size:14pt">菜单资源</span><br><span style="font-size:14pt">制作好菜单资源后,在对话框的Menu属性中选择刚才制作好的对话框。</span><br><span style="font-size:
733 0
总结:MFC中一个对话框的关闭过程 .
说起来挺简单的,一个对话框关闭时要依次调用该类的DestroyWindow-OnDestroy-PostNcDestroy,根据关闭的方法不同,在这些函数之前会调用OnOK、OnCancle或者OnClose。
633 0
Silverlight中多个Xaml("场景"? or "窗口"? )之间的切换/调用/弹出/传参数问题小结
silverlight中不存在Flash中的场景,有的只是一个个Xaml文件,你要是愿意,也可以把它看做"场景"或"窗口",刚开始接触sl时,对于多个xaml之间如何切换,调用,传递参数感到很棘手,下面是我总结的几种方法: 1、A.
786 0
可以弹出确认对话框的自定义Web服务器控件ConfirmButton
经常在论坛里看到类似这样的问题:“…如何在点击删除按钮的时候弹出个确认删除对话框”。      下面我们来自己写一个这样的自定义Web服务器控件!      思路如下:      继承System.Web.UI.WebControls.Button控件      增加一个属性“ConfirmMessage”来表示弹出确认框上面的提示信息。
516 0
弹出自定义窗口
1.window对象的open方法  window的open方法用于创建一个新窗口,语法如下 window.open(URL,windowname[,windowFeatures][,replaceFlag]) URL: 弹出窗口的URL地址 windowname:弹出窗口的名称,可为空 windowFeature:字符串值,是由逗号分隔的属性赋值表达式,下表为window.
461 0
在Dll中创建对话框并调用
1、第一步创建一“MFC AppWizard (dll)”工程,接下来选择“Regular Dll using shared MFC DLL”,点击“Finish”。 2、添加一对话框资源到工程中,从菜单中选择Insert->Resource,添加一“Dialog”选择“New”,至此对话框已添加到DLL工程中。
720 0
+关注
行者武松
杀人者,打虎武松也。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载