WCF入门示例一:承载于托管代码中的WCF示例程序

下面的实例我们将创建一个承载于托管代码中的WCF示例程序.开发工具是VS2010, .NET FrameWork 4.0.

这个示例主要概念是,建一个WCF服务提供程序,提供加减乘除的运算,然后再建一个客户端调用程序来调用WCF服务上的方法.下面是完成后的程序框架的截图:

 

下面我们开始示例程序

1.打开VS2010-->File-->New-->Project. 在弹出的对话框中,按照下面填写.

2.点击OK按钮,创建一个普通的控制台应用程序.

3.引入System.ServiceModel.dll. 因为在下面创建服务协定的时候需要用到此类库.右键单击References-->Add References. 在弹出的对话框中,按照下面选择,点击OK按钮.

4.现在创建一个服务协定,也就是新建一个接口.为接口应用ServiceContractAttribute特性, 为接口中的4个方法应用OperationContractAttribute特性.

这也是WCF协定于普通接口不同之处.带有[ServiceContract]特性的接口说明是WCF公开的协议;带有[OperationContract]特性的方法说明是协议公开的方法. 完整代码如下:

ICalculator.cs

using System;
// Step 5: Add the using statement for the System.ServiceModel namespace
using System.ServiceModel;
namespace Microsoft.ServiceModel.Samples
{
    // Step 6: Define a service contract.
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        // Step7: Create the method declaration for the contract.
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }
}

 5.实现服务协定,也就是创建一个类,并实现接口的方法.

这个类需要继承于ICalculator接口,并实现ICalculator接口的方法.这个类的方法会由WCF服务提供给客户端调用.

 CalculatorService.cs

using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
    // Step 1: Create service class that implements the service contract.
    public class CalculatorService : ICalculator
    {
        // Step 2: Implement functionality for the service operations.
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            // Code added to write output to the console window.
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            Console.WriteLine("Received Subtract({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            Console.WriteLine("Received Multiply({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            Console.WriteLine("Received Divide({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
    }
}

6.创建服务承载程序,也就是WCF服务的宿主.

这个类主要是对WCF做一些服务器端的配置和绑定.注意这行的代码 selfHost.AddServiceEndpoint( typeof(ICalculator),  new WSHttpBinding(),  "CalculatorService");实现了把协议绑定到主机.

Program.cs

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
    class Program
    {
        static void Main(string[] args)
        {

            // Step 1 of the address configuration procedure: Create a URI to serve as the base address.
            Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

            // Step 2 of the hosting procedure: Create ServiceHost
            ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

            try
            {
                // Step 3 of the hosting procedure: Add a service endpoint.
                selfHost.AddServiceEndpoint(
                    typeof(ICalculator),
                    new WSHttpBinding(),
                    "CalculatorService");

                // Step 4 of the hosting procedure: Enable metadata exchange.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                // Step 5 of the hosting procedure: Start (and then stop) the service.
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // Close the ServiceHostBase to shutdown the service.
                selfHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }

        }
    }

}

这是创建好的服务项目截图

到这一步我们的服务已经可以运行了.它提供了加减乘除4个方法供客户端调用.我们可以试运行一下服务,看看效果.导航到项目目录下,双击WcfServiceDemo.exe. 具体目录取决于自己的电脑上项目的位置.

显示服务已经运行.

打开 Internet Explorer,并浏览到服务的调试页(网址为 http://localhost:8000/ServiceModelSamples/Service)

 

写过WebService的同学,觉得这个页面看起来是不是很熟悉.

点击http://localhost:8000/ServiceModelSamples/Service?wsdl,可以浏览CalculatorService Service的详细描述. 有了这些描述信息,其他平台或公司的开发人员就可以根据这些描述来调用你的WCF程序了.

View Code
<?xml version="1.0" encoding="UTF-8"?>
-<wsdl:definitions xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:i0="http://Microsoft.ServiceModel.Samples" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://tempuri.org/" name="CalculatorService">-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">-<wsp:Policy>-<sp:ProtectionToken>-<wsp:Policy>-<sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">-<wsp:Policy><sp:RequireDerivedKeys/>-<sp:BootstrapPolicy>-<wsp:Policy>-<sp:SignedParts><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts><sp:Body/></sp:EncryptedParts>-<sp:SymmetricBinding>-<wsp:Policy>-<sp:ProtectionToken>-<wsp:Policy>-<sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">-<wsp:Policy><sp:RequireDerivedKeys/></wsp:Policy></sp:SpnegoContextToken></wsp:Policy></sp:ProtectionToken>-<sp:AlgorithmSuite>-<wsp:Policy><sp:Basic256/></wsp:Policy></sp:AlgorithmSuite>-<sp:Layout>-<wsp:Policy><sp:Strict/></wsp:Policy></sp:Layout><sp:IncludeTimestamp/><sp:EncryptSignature/><sp:OnlySignEntireHeadersAndBody/></wsp:Policy></sp:SymmetricBinding>-<sp:Wss11><wsp:Policy/></sp:Wss11>-<sp:Trust10>-<wsp:Policy><sp:MustSupportIssuedTokens/><sp:RequireClientEntropy/><sp:RequireServerEntropy/></wsp:Policy></sp:Trust10></wsp:Policy></sp:BootstrapPolicy></wsp:Policy></sp:SecureConversationToken></wsp:Policy></sp:ProtectionToken>-<sp:AlgorithmSuite>-<wsp:Policy><sp:Basic256/></wsp:Policy></sp:AlgorithmSuite>-<sp:Layout>-<wsp:Policy><sp:Strict/></wsp:Policy></sp:Layout><sp:IncludeTimestamp/><sp:EncryptSignature/><sp:OnlySignEntireHeadersAndBody/></wsp:Policy></sp:SymmetricBinding>-<sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><wsp:Policy/></sp:Wss11>-<sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">-<wsp:Policy><sp:MustSupportIssuedTokens/><sp:RequireClientEntropy/><sp:RequireServerEntropy/></wsp:Policy></sp:Trust10><wsaw:UsingAddressing/></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Add_Input_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Add_output_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Subtract_Input_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Subtract_output_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Multiply_Input_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Multiply_output_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Divide_Input_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy>-<wsp:Policy wsu:Id="WSHttpBinding_ICalculator_Divide_output_policy">-<wsp:ExactlyOne>-<wsp:All>-<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="To"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="From"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="FaultTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="MessageID"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="RelatesTo"/><sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action"/></sp:SignedParts>-<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"><sp:Body/></sp:EncryptedParts></wsp:All></wsp:ExactlyOne></wsp:Policy><wsdl:import location="http://localhost:8000/ServiceModelSamples/Service?wsdl=wsdl0" namespace="http://Microsoft.ServiceModel.Samples"/><wsdl:types/>-<wsdl:binding name="WSHttpBinding_ICalculator" type="i0:ICalculator"><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_policy"/><soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>-<wsdl:operation name="Add"><soap12:operation style="document" soapAction="http://Microsoft.ServiceModel.Samples/ICalculator/Add"/>-<wsdl:input><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Add_Input_policy"/><soap12:body use="literal"/></wsdl:input>-<wsdl:output><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Add_output_policy"/><soap12:body use="literal"/></wsdl:output></wsdl:operation>-<wsdl:operation name="Subtract"><soap12:operation style="document" soapAction="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract"/>-<wsdl:input><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Subtract_Input_policy"/><soap12:body use="literal"/></wsdl:input>-<wsdl:output><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Subtract_output_policy"/><soap12:body use="literal"/></wsdl:output></wsdl:operation>-<wsdl:operation name="Multiply"><soap12:operation style="document" soapAction="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply"/>-<wsdl:input><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Multiply_Input_policy"/><soap12:body use="literal"/></wsdl:input>-<wsdl:output><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Multiply_output_policy"/><soap12:body use="literal"/></wsdl:output></wsdl:operation>-<wsdl:operation name="Divide"><soap12:operation style="document" soapAction="http://Microsoft.ServiceModel.Samples/ICalculator/Divide"/>-<wsdl:input><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Divide_Input_policy"/><soap12:body use="literal"/></wsdl:input>-<wsdl:output><wsp:PolicyReference URI="#WSHttpBinding_ICalculator_Divide_output_policy"/><soap12:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding>-<wsdl:service name="CalculatorService">-<wsdl:port name="WSHttpBinding_ICalculator" binding="tns:WSHttpBinding_ICalculator"><soap12:address location="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"/>-<wsa10:EndpointReference><wsa10:Address>http://localhost:8000/ServiceModelSamples/Service/CalculatorService</wsa10:Address>-<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"><Upn>SZX-STATION168\Administrator</Upn></Identity></wsa10:EndpointReference></wsdl:port></wsdl:service></wsdl:definitions>

7.下面我们创建一个可以调用此服务的客户端.我们还是创建一个控制台项目.

打开VS2010-->File-->New-->Project. 在弹出的对话框中,按照下面填写.

 点击OK按钮完成添加. 跟服务器端程序一样,客户端程序也需要引用System.ServiceModel.dll.

8.VS2010提供的ServiceModel 元数据实用工具 (Svcutil.exe) 可以方便的创建客户端代码和配置文件. 我们这里就演示如何使用Svcutil.exe来配置客户端.

开始菜单-->所有程序-->Microsoft Visual Studio 2010-->Visual Studio Tools-->Visual Studio Command Prompt (2010). 打开VS2010命令提示行.接着导航到要放置客户端代码的目录。如果使用默认值创建客户端项目,则该目录为 C:\Users\<用户名>\My Documents\Visual Studio 10\Projects\Service\Client. 我对应的路径是D:\visual studio 2010\Projects\WCF\WcfServiceDemo\WcfClient.

在执行下面的命令前需要先启动WCF服务程序,也就是前面的WcfServiceDemo.exe,否则会报错.

接着执行如下命令 svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8000/ServiceModelSamples/service

运行完毕后,我们可以看到在WcfClient目录下生成了两个新文件,有了这两个文件我们就可以在客户端调用WCF服务程序上的方法了.


 回到VS2010 IDE界面,将新生成的两个文件包含到WcfClient项目中.

这两个文件,一个是配置文件,一个是代理类;其实这两个文件完全可以自己手工写,但是既然可以自动生成,我们就偷点懒,使用Svcutil工具自动生成.下面是这两个文件的详细内容.

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_ICalculator" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
                contract="ICalculator" name="WSHttpBinding_ICalculator">
                <identity>
                    <userPrincipalName value="SZX-STATION168\Administrator" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

generatedProxy.cs

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.296
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="ICalculator")]
public interface ICalculator
{
    
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
    double Add(double n1, double n2);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")]
    double Subtract(double n1, double n2);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")]
    double Multiply(double n1, double n2);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")]
    double Divide(double n1, double n2);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface ICalculatorChannel : ICalculator, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class CalculatorClient : System.ServiceModel.ClientBase<ICalculator>, ICalculator
{
    
    public CalculatorClient()
    {
    }
    
    public CalculatorClient(string endpointConfigurationName) : 
            base(endpointConfigurationName)
    {
    }
    
    public CalculatorClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }
    
    public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }
    
    public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress)
    {
    }
    
    public double Add(double n1, double n2)
    {
        return base.Channel.Add(n1, n2);
    }
    
    public double Subtract(double n1, double n2)
    {
        return base.Channel.Subtract(n1, n2);
    }
    
    public double Multiply(double n1, double n2)
    {
        return base.Channel.Multiply(n1, n2);
    }
    
    public double Divide(double n1, double n2)
    {
        return base.Channel.Divide(n1, n2);
    }
}

9.使用客户端调用WCF服务.

将program.cs重命名为Client, 并添加下面的代码.下面的代码是不是很熟悉,就像是一般的C#程序代码. 其实它就是实现了调用WCF服务的程序.

Client.cs

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

namespace ServiceModelSamples
{

    class Client
    {
        static void Main()
        {
            //Step 1: Create an endpoint address and an instance of the WCF Client.
            CalculatorClient client = new CalculatorClient();


            // Step 2: Call the service operations.
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            //Step 3: Closing the client gracefully closes the connection and cleans up resources.
            client.Close();


            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();

        }
    }
}

到这一步一个完整的WCF服务和客户端程序已经完成了.我们运行客户端程序看看效果.记住在运行客户端之前需要先启动WCF服务程序.我机器上WCF服务和客户端分别在以下位置:

D:\visual studio 2010\Projects\WCF\WcfServiceDemo\WcfServiceDemo\bin\Debug\WcfServiceDemo.exe 

D:\visual studio 2010\Projects\WCF\WcfServiceDemo\WcfClient\bin\Debug\WcfClient.exe

客户端截图:

服务器端截图:

至此,一个WCF服务的创建和调用已经完成. 示例没有对程序细节做过多的解释,如定义服务协定,实现服务协定,绑定类型等. 本示例旨在演示如何创建一个可以运行的WCF服务程序, 通过完成示例,达到对WCF有个大概的了解.这个示例主要取材于MSDN上的例子,有兴趣的同学可以去看看http://msdn.microsoft.com/zh-cn/library/ms734712(v=vs.100).aspx,那里的介绍比我的详细很多.

原文地址:https://www.cnblogs.com/dongdonggege/p/2831025.html