1、创建WCF服务库
打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→WCF→WCF服务库,然后输入项目名称(Name),存放位置(Location)和解决方案名称(Solution Name),点击“确定”生成项目。如下图:
2、添加服务操作,本示例中添加了一个Add的加法服务操作
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace WcfServiceLibrary1 { // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。 [ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: 在此添加您的服务操作 [OperationContract] int Add(int i, int j); } // 使用下面示例中说明的数据协定将复合类型添加到服务操作 [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace WcfServiceLibrary1 { // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。 [ServiceBehavior(IncludeExceptionDetailInFaults=true)] public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } public int Add(int i, int j) { return i + j; } } }
这里需要注意一下:如果获取文件失败,程序抛出一个SoapException。但是,缺省地,WCF不会暴露异常的细节给客户端,所以客户端要想能获得异常的细节,需要在此再做两件事。
首先,将App.config的serviceDebug节点的参数includeExceptionDetailInFaults设置改为True,即:<serviceDebug includeExceptionDetailInFaults="True" />
App.config的代码:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <compilation debug="true" /> </system.web> <!-- 部署服务库项目时,必须将配置文件的内容添加到 主机的 app.config 文件中。System.Configuration 不支持库的配置文件。--> <system.serviceModel> <services> <service name="WcfServiceLibrary1.Service1"> <host> <baseAddresses> <add baseAddress = "http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- 除非完全限定,否则地址将与上面提供的基址相关 --> <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1"> <!-- 部署时,应删除或替换下列标识元素,以反映 用来运行所部署服务的标识。删除之后,WCF 将 自动推断相应标识。 --> <identity> <dns value="localhost"/> </identity> </endpoint> <!-- Metadata Endpoints --> <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除--> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior> <!-- 为避免泄漏元数据信息, 请在部署前将以下值设置为 false 并删除上面的元数据终结点 --> <serviceMetadata httpGetEnabled="True"/> <!-- 要接收故障异常详细信息以进行调试, 请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息--> <serviceDebug includeExceptionDetailInFaults="True" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
其次,如上面代码,在class Service1声明前加ServiceBehavior特性,即:
[ServiceBehavior(IncludeExceptionDetailInFaults=true)] public class Service1 : IService1 {}
这样WCF的服务库,我们就建好了,接下来是在客户端进行调用了!
3、右键解决方案→添加→新建项目,在打开的添加新项目对话框中,依次选择Visual C#→Window→控制台应用程序,然后输入项目名称(Name),存放位置(Location),点击“确定”,如下图:
4、对新建的WcfClientConsoleApplication客户端,右键添加服务引用,弹出添加服务引用对话框,点击发现或前往,如果是点击前往,需要在地址上输入WCF服务库的App.config的baseAddresses节点的<add baseAddress = "http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />的值,找到服务后,修改命名空间,点击确定,项目自动生成服务。如下图:
5、在客户端(控制台应用程序)中调用WCF服务操作
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WcfClientConsoleApplication { class Program { static void Main(string[] args) { try { WcfServiceReference1.Service1Client sc = new WcfServiceReference1.Service1Client(); int sum = sc.Add(12, 21); Console.WriteLine(sum); Console.ReadKey(); } catch (TimeoutException ex) { Console.WriteLine("TimeoutException-{0}",ex.Message); } catch (FaultException ex) { Console.WriteLine("FaultException-{0}", ex.Message); } catch (InvalidOperationException ex) { Console.WriteLine("InvalidOperationException-{0}", ex.Message); } catch (CommunicationException ex) { Console.WriteLine("CommunicationException-{0}", ex.Message); } catch (Exception ex) { Console.WriteLine("Exception-{0}", ex.Message); } } } }