创建WCF 服务客户端应用程序需要执行下列步骤:
WCF客户端调用服务存在以下特点:
WCF客户端调用服务方式:
WCF客户端调用服务实例:
Service:类库程序,定义服务契约和实现,里面包含User数据契约和GetInfo()获取用户信息的服务契约方法。
IUserInfo.cs的代码如下:
adb961" class="code_img_closed" src="/Upload/Images/2015040811/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('d581b31c-4eed-4869-b5af-fbbe5badb961',event)" src="/Upload/Images/2015040811/2B1B950FA3DF188F.gif" alt="" />using System.ServiceModel; using System.Collections.Generic; using System.Runtime.Serialization; namespace Service { [ServiceContract] public interface IUserInfo { [OperationContract] User[] GetInfo(int? id=null); } [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; } } }View Code
UserInfo.cs的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Service { public class UserInfo:IUserInfo { public User[] GetInfo(int? id=null) { List<User> Users = new List<User>(); Users.Add(new User { ID = 1, Name = "JACK", Age = 20, Nationality = "CHINA" }); Users.Add(new User { ID = 2, Name = "TOM", Age = 18, Nationality = "JAPAN" }); Users.Add(new User { ID = 3, Name = "SMITH", Age = 22, Nationality = "KOREA" }); Users.Add(new User { ID = 4, Name = "ALENCE", Age = 21, Nationality = "INDIA" }); Users.Add(new User { ID = 5, Name = "JOHN", Age = 22, Nationality = "SINGAPORE" }); if (id != null) { return Users.Where(x => x.ID == id).ToArray(); } else { return Users.ToArray(); } } } }View Code
Host:控制台应用程序,添加对Service程序集的引用,寄宿服务程序。
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(UserInfo))) { host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); }; host.Open(); Console.Read(); } } } }View Code
App.config代码如下:
<?xml version="1.0"?> <configuration> <system.serviceModel> <services> <service name="Service.UserInfo" behaviorConfiguration="mexBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:1234/UserInfo/"/> </baseAddresses> </host> <endpoint address="" binding="wsHttpBinding" contract="Service.IUserInfo" /> <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>View Code
Client1:控制台应用程序,添加对服务终结点地址http://localhost:1234/UserInfo/的引用,设置服务命名空间为UserInfoServiceRef,生成客户端代理类和配置文件代码后,完成Client1对服务的调用。
Program.cs的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Client1.UserInfoServiceRef; namespace Client1 { 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(); } } }View Code
Client2:控制台应用程序,使用svcutil.exe工具生成客户端代理类,在命令行中输入以下命令:
1.在运行中输入cmd打开命令行,输入 cd C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
2.输入svcutil.exe /out:f:\ UserInfoClient.cs /config:f:\App.config http://localhost:1234/UserInfo/ (注意:端口号改成本机服务寄宿的端口号)
3.将生成的App.config和UserInfoClient.cs复制到Client2的工程目录下,完成Program.cs代码,代码和Client1的代码一样。
Client3:控制台应用程序,添加对Service程序集的引用,完成Program.cs代码,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Service; using System.ServiceModel; using System.ServiceModel.Channels; namespace Client3 { class Program { static void Main(string[] args) { EndpointAddress address = new EndpointAddress("http://localhost:1234/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(); } } }View Code
查看服务运行结果,结果如下图所示:
namespace Service { using System.Runtime.Serialization; [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="User", Namespace="http://schemas.datacontract.org/2004/07/Service")] public partial class User : object, System.Runtime.Serialization.IExtensibleDataObject { private System.Runtime.Serialization.ExtensionDataObject extensionDataField; private int AgeField; private int IDField; private string NameField; private string NationalityField; public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public int Age { get { return this.AgeField; } set { this.AgeField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public int ID { get { return this.IDField; } set { this.IDField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public string Name { get { return this.NameField; } set { this.NameField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public string Nationality { get { return this.NationalityField; } set { this.NationalityField = value; } } } } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="IUserInfo")] public interface IUserInfo { [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IUserInfo/GetInfo", ReplyAction="http://tempuri.org/IUserInfo/GetInfoResponse")] Service.User[] GetInfo(System.Nullable<int> id); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public interface IUserInfoChannel : IUserInfo, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class UserInfoClient : System.ServiceModel.ClientBase<IUserInfo>, IUserInfo { public UserInfoClient() { } public UserInfoClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public UserInfoClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public UserInfoClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public UserInfoClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public Service.User[] GetInfo(System.Nullable<int> id) { return base.Channel.GetInfo(id); } }
我们可以看到客户端代理类中有着数据契约、服务契约,并且客户端代理类UserInfoClient继承ClientBase<IUserInfo>, IUserInfo,通过WCF内部通道机制完成对服务的调用。
public Service.User[] GetInfo(System.Nullable<int> id)
{
returnbase.Channel.GetInfo(id);
}
EndpointAddress address = new EndpointAddress("http://localhost:1234/UserInfo");
WSHttpBinding binding = new WSHttpBinding();
ChannelFactory<IUserInfo> factory = new ChannelFactory<IUserInfo>(binding,address);
IUserInfochannel = factory.CreateChannel();
创建通道,完成对WCF服务的调用,注意:此处的工厂虽然提供了很多重载的方法,但我们这里属于客户端代码编程,因此我们读取不到配置文件信息,所以我把终结点信息和绑定信息写到了代码中,如果想通过ChannelFactory<IUserInfo>读取配置文件信息,我们需要手动实现其扩展机制。这里以后的博文再做讨论