WCF系列教程之WCF客戶端調用服務


1、創建WCF客戶端應用程序需要執行下列步驟

(1)、獲取服務終結點的服務協定、綁定以及地址信息

(2)、使用該信息創建WCF客戶端

(3)、調用操作

(4)、關閉WCF客戶端對象

 

二、操作實例

 

1、WCF服務層搭建:新建契約層、服務層、和WCF宿主,添加必須的引用(這里不會的參考本人前面的隨筆),配置宿主,生成解決方案,打開Host.exe,開啟服務。具體的代碼如下:

ICalculate.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace IService
{
    [ServiceContract]
    public interface ICalculate
    {
        [OperationContract]
        int Add(int a, int b);
    }
}

IUserInfo.cs

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

namespace IService
{
    [ServiceContract]
    public interface IUserInfo
    {
        [OperationContract]
        User[] GetInfo(int? id);
    }

    [DataContract]
    public class User
    {
        [DataMember]
        public int ID { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
        [DataMember]
        public string Nationality { get; set; }  
    }
}

注:必須引入System.Runtime.Serialization命名空間,應為User類在被傳輸時必須是可序列化的,否則將無法傳輸

Calculate.cs

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    public class Calculate : ICalculate
    {
        public int Add(int a, int b)
        {
            return a + b;
        }
    }
}

UserInfo.cs

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    public class UserInfo : IUserInfo
    {
        public User[] GetInfo(int? id)
        {
            List<User> Users = new List<User>();
            Users.Add(new User { ID = 1, Name = "張三", Age = 11, Nationality = "China" });
            Users.Add(new User { ID = 2, Name = "李四", Age = 12, Nationality = "English" });
            Users.Add(new User { ID = 3, Name = "王五", Age = 13, Nationality = "American" });

            if (id != null)
            {
                return Users.Where(x => x.ID == id).ToArray();
            }
            else
            {
                return Users.ToArray();
            }
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service;
using System.ServiceModel;

namespace Host
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(Calculate)))
            {
                host.Opened += delegate { Console.WriteLine("服務已經啟動,按任意鍵終止!"); };
                host.Open();
                Console.Read();
            }
        }
    }
}

App.Config

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>

    <services>
      <service name="Service.Calculate" behaviorConfiguration="mexBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/Calculate/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="IService.ICalculate" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

ok,打開Host.exe

服務開啟成功!

2、新建名為Client的客戶端控制台程序,通過添加引用的方式生成WCF客戶端

確保Host.exe正常開啟的情況下,添加對服務終結點地址http://localhost:6666/UserInfo/的引用,,設置服務命名空間為UserInfoClientNS

點擊確定完成添加,生成客戶端代理類和配置文件代碼后,

開始Client客戶端控制台程序對WCF服務的調用,Program.cs代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Client.UserInfoClientNS;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            UserInfoClient proxy =new UserInfoClient();
            User[] Users = proxy.GetInfo(null);
            Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}","ID","Name","Age","Nationality");
            for(int i=0;i<Users.Length;i++)
            {
                  Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}",
                    Users[i].ID.ToString(),
                    Users[i].Name.ToString(),
                    Users[i].Age.ToString(),
                    Users[i].Nationality.ToString());
            }

            Console.Read();
        }
        
    }
}

 

ok,第一種客戶端添加引用的方式測試成功

 

3、新建名為Client1的客戶端控制台程序,通過svcutil.exe工具生成客戶端代理類的方式生成WCF客戶端,在VS2012 開發人員命令提示中輸入以下命令:

(1)、定位到當前客戶端所在的盤符

(2)、定位當前客戶端所在的路徑

 

(3)、svcutil http://localhost:8000/OneWay/?wsdl /o:OneWay.cs      這里是OneWay,你本地是什么就是什么

(4)、生成客戶端代理類,生成成功之后,將文件添加到項目中

ok,生成成功!

(5)、將生成的文件包括到項目中,引入System.Runtime.Serialization命名空間和System.ServiceModel命名空間

(6)、確保服務開啟的情況下,開始調用,Program.cs代碼如下:

UserInfoClient proxy = new UserInfoClient();
            User[] Users = proxy.GetInfo(null);
            Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", "ID", "Name", "Age", "Nationality");
            for (int i = 0; i < Users.Length; i++)
            {
                Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}",
                  Users[i].ID.ToString(),
                  Users[i].Name.ToString(),
                  Users[i].Age.ToString(),
                  Users[i].Nationality.ToString());
            }

            Console.Read();

ok,服務調用成功,說明使用svcutil工具生成WCF客戶端的方式可行。

 

4、通過添加對Service程序集的引用,完成對WCF服務端的調用,新建一個Client2客戶端控制台程序

先添加下面三個引用

using IService;
using System.ServiceModel;
using System.ServiceModel.Channels;

(1)、Program.cs代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using IService;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;



namespace Client2
{
    class Program
    {
        static void Main(string[] args)
        {
            EndpointAddress address = new EndpointAddress("http://localhost:6666/UserInfo/");
            WSHttpBinding binding = new WSHttpBinding();
            ChannelFactory<IUserInfo> factory = new ChannelFactory<IUserInfo>(binding, address);
            IUserInfo channel = factory.CreateChannel();


            User[] Users = channel.GetInfo(null);
            Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", "ID", "Name", "Age", "Nationality");
            for (int i = 0; i < Users.Length; i++)
            {
                Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}",
                  Users[i].ID.ToString(),
                  Users[i].Name.ToString(),
                  Users[i].Age.ToString(),
                  Users[i].Nationality.ToString());
            }

            ((IChannel)channel).Close();
            factory.Close();
            Console.Read();
        }
    }
}

ok,調用成功!

 

三、歸納總結

通過上面的代碼判斷WCF客戶端調用服務存在以下特點:

1、WCF服務端可客戶端通過使用托管屬性、接口、方法對協定進行建模。若要連接到服務端的服務,則需要獲取該服務協定的類型信息.獲取協定的類型信息有兩種方式:

(1)、通過Svcutil工具,在客戶端生成代理類的方式,來獲取服務端服務的服務協定的類型信息

(2)、通過給項目添加服務引用的方式

上面兩種方式都會從服務端的服務中下載元數據,並使用當前你使用的語言,將其轉換成托管源代碼文件中,同時還創建一個您可用於配置 WCF 客戶端對象的客戶端應用程序配置文件.

2、WCF客戶端是表示某個WCF服務的本地對象,客戶端可以通過該本地對象與遠程服務進行通信。因此當你在服務端創建了一個服務端協定,並對其進行配置后,客戶端就可以通過生成代理類的方式(具體生成代理類的方式,上面已經提了)和服務端的服務進行通信,WCF 運行時將方法調用轉換為消息,然后將這些消息發送到服務,偵聽回復,並將這些值作為返回值或 out 參數(或 ref 參數)返回到 WCF 客戶端對象中.(有待考證);

3、創建並配置了客戶端對象后,請創建一個 try/catch 塊,如果該對象是本地對象,則以相同的方式調用操作,然后關閉 WCF 客戶端對象。 當客戶端應用程序調用第一個操作時,WCF 將自動打開基礎通道,並在回收對象時關閉基礎通道。 (或者,還可以在調用其他操作之前或之后顯式打開和關閉該通道。)。不應該使用 using 塊來調用WCF服務方法。因為C# 的“using”語句會導致調用 Dispose()。 它等效於 Close(),當發生網絡錯誤時可能會引發異常。 由於對 Dispose() 的調用是在“using”塊的右大括號處隱式發生的,因此導致異常的根源往往會被編寫代碼和閱讀代碼的人所忽略。 這是應用程序錯誤的潛在根源

 


免責聲明!

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



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