WCF入門及在WinForm中動態調用


一、WCF入門

1. 新建立空白解決方案,並在解決方案中新建項目,項目類型為:WCF服務應用程序,刪除系統生成的兩個文件IService1.cs與Service1.svc, 添加自定義的WCF【服務文件】User.svc。建立完成后如下圖所示:

 

2、在IUser.cs中添加方法ShowName接口和在User.svc中時間方法,如圖:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServer
{
    // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的接口名“IUser”。
    [ServiceContract]
    public interface IUser
    {
        [OperationContract]
        string ShowName(string name);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServer
{
    // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼、svc 和配置文件中的類名“User”。
    public class User : IUser
    {
        public string ShowName(string name)
        {
            string wcfName = string.Format("WCF服務,顯示姓名:{0}", name);
            return wcfName;
        }
    }
}

大家可以看到,在WCF中的接口與普通接口的區別只在於兩個上下文,其他的和我們正常學習的接口一樣。定義這個上下文要添加System.ServiceModel的引用。

[ServiceContract],來說明接口是一個WCF的接口,如果不加的話,將不能被外部調用。

[OperationContract],來說明該方法是一個WCF接口的方法,不加的話同上。 

此時我們的第一個WCF服務程序就建立好了,將User.svc“設為起始頁”,然后F5運行一下試試,如下圖所示,VS2010自動調用了WCF的客戶端測試工具以便我們測試程序:

我們雙擊上圖中的 ShowName() 方法,測試一下方法,出現如下圖:

4、在游覽器中出現如下圖所示,說明服務部署成功。

二、客戶端動態調用WCF

1、新建WinForm程序,添加WCF訪問接口類:

 
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.ServiceModel;
 using System.ServiceModel.Channels;
 using System.Reflection;
 
 namespace WcfClient
 {
     /// <summary>
     /// 使用ChannelFactory為wcf客戶端創建獨立通道
     /// </summary>
     public class WcfChannelFactory
     {
         public WcfChannelFactory()
         {
         }
 
         /// <summary>
         /// 執行方法   WSHttpBinding
         /// </summary>
         /// <typeparam name="T">服務接口</typeparam>
         /// <param name="uri">wcf地址</param>
         /// <param name="methodName">方法名</param>
         /// <param name="args">參數列表</param>
         public static object ExecuteMetod<T>(string uri, string methodName, params object[] args)
         {
             //BasicHttpBinding binding = new BasicHttpBinding();   //出現異常:遠程服務器返回錯誤: (415) Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'.。
             WSHttpBinding binding = new WSHttpBinding();
             EndpointAddress endpoint = new EndpointAddress(uri);
 
             using (ChannelFactory<T> channelFactory = new ChannelFactory<T>(binding, endpoint))
             {
                 T instance = channelFactory.CreateChannel();
                 using (instance as IDisposable)
                 {
                     try
                     {
                         Type type = typeof(T);
                         MethodInfo mi = type.GetMethod(methodName);
                         return mi.Invoke(instance, args);
                     }
                     catch (TimeoutException)
                     {
                         (instance as ICommunicationObject).Abort();
                         throw;
                     }
                     catch (CommunicationException)
                     {
                         (instance as ICommunicationObject).Abort();
                         throw;
                     }
                     catch (Exception vErr)
                     {
                         (instance as ICommunicationObject).Abort();
                         throw;
                     }
                 }
             }
 
 
         }
 
 
         //nettcpbinding 綁定方式
         public static object ExecuteMethod<T>(string pUrl, string pMethodName,params object[] pParams)
         {
                 EndpointAddress address = new EndpointAddress(pUrl);
                 Binding bindinginstance = null;
                 BasicHttpBinding ws = new BasicHttpBinding();
                 ws.MaxReceivedMessageSize = 20971520; 
                 bindinginstance = ws;
                 using (ChannelFactory<T> channel = new ChannelFactory<T>(bindinginstance, address))
                 {
                     T instance = channel.CreateChannel();
                     using (instance as IDisposable)
                     {
                         try
                         {
                             Type type = typeof(T);
                             MethodInfo mi = type.GetMethod(pMethodName);
                             return mi.Invoke(instance, pParams);
                         }
                         catch (TimeoutException)
                         {
                             (instance as ICommunicationObject).Abort();
                             throw;
                         }
                         catch (CommunicationException)
                         {
                             (instance as ICommunicationObject).Abort();
                             throw;
                         }
                         catch (Exception vErr)
                         {
                             (instance as ICommunicationObject).Abort();
                             throw;
                         }
                     }
                 }
         }
     }
 }

2、添加接口IUser.cs文件,把服務端的IUser.cs文件拷貝過來:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfClient
{
    // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的接口名“IUser”。
    [ServiceContract]
    public interface IUser
    {
        [OperationContract]
        string ShowName(string name);
    }
}

 

3、調用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
using System.ServiceModel;

namespace WcfClient
{
    public partial class Form1 : Form
    {
         
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string uri = "http://localhost:32904/User.svc?wsdl"; 
             object o = WcfChannelFactory.ExecuteMethod<IUser>(uri, "ShowName", this.textBox1.Text.Trim());
             this.label1.Text = string.Format("服務:{0}", o.ToString());
       
        }

      
         
    }
}

4結果如圖:

調用:

 

 

注意:WCF的bing方式,根據服務器的配置來,選擇合適的bing方式:

WCF中常用的binding方式:

BasicHttpBinding: 用於把 WCF 服務當作 ASMX Web 服務。用於兼容舊的Web ASMX 服務。
WSHttpBinding: 比 BasicHttpBinding 更加安全,通常用於 non-duplex 服務通訊。
WSDualHttpBinding: 和 WSHttpBinding 相比,它支持 duplex 類型的服務。
WSFederationHttpBinding: WS-Federation 安全通訊協議。
NetTcpBinding: 使用 TCP 協議,用於在局域網(Intranet)內跨機器通信。有幾個特點:可靠性、事務支持和安全,優化了 WCF 到 WCF 的通信。限制是服務端和客戶端都必須使用 WCF 來實現。
NetNamedPipeBinding: 使用命名管道進行安全、可靠、高效的單機服務通訊方式。
NetMsmqBinding: 使用消息隊列在不同機器間進行非連接通訊。
NetPeerTcpBinding: 使用 P2P 協議在多機器間通訊。
MsmqIntegrationBinding: 將 WCF 消息轉化為 MSMQ 消息,使用現有的消息隊列系統進行跨機器通訊。如MSMQ。

名稱

傳輸

編碼

共同操作

BasicHttpBinding

HTTP/HTTPS

Text

Yes

NetTcpBinding

TCP

Binary

No

NetPeerTcpBinding

P2P

Binary

No

NetNamedPipeBinding

IPC

Binary

No

WSHttpBinding

HTTP/HTTPS

Text,MTOM

Yes

WSFederationBinding

HTTP/HTTPS

Text,MTOM

Yes

WSDualHttpBinding

HTTP

Text,MTOM

Yes

NetMsmqBinding

MSMQ

Binary

No

MsmqIntegrationBinding

MSMQ

Binary

Yes

 

Binding名稱

Configuration Element

描述

BasicHttpBinding

basicHttpBinding

一個指定用符合基本網絡服務規范通訊的binding,它用http進行傳輸,數據格式為text/xml

WSHttpBinding

wsHttpBinding

一個安全的通用的binding,但它不能在deplex中使用

WSDualHttpBinding

wsDualHttpBinding

一個安全的通用的binding,但能在deplex中使用

WSFederationHttpBinding

wsFederationHttpBinding

一個安全的通用的支持WSF的binding,能對用戶進行驗證和授權

NetTcpBinding

netTcpBinding

在wcf應用程序中最適合跨機器進行安全通訊的binding

NetNamedPipeBinding

netNamedPipeBinding

在wcf應用程序中最適合本機進行安全通訊的binding

NetMsmqBinding

netMsmqBinding

在wcf應用程序中最適合跨機器進行安全通訊的binding,並且支持排隊

NetPeerTcpBinding

netPeerTcpBinding

一個支持安全的,多機交互的binding

 

msmqIntegrationBinding

 

下載源碼地址:http://download.csdn.net/detail/ffuqiaoq/8537793

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM