转 如何在调用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接口中:

: [ServiceContract(Name = "CalculatorService", Namespace ="http://www.artech.com/")]
    2: [InvocationConfirmationBehavior]
    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: }

  

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: }
原文地址:https://www.cnblogs.com/xiangxiong/p/7444821.html