WCF学习

相关链接

http://www.cnblogs.com/iamlilinfeng/p/4083827.html

http://www.cnblogs.com/iamlilinfeng/archive/2012/10/01/2706353.html

1、项目目录

主目录

服务库目录

 

三种宿主目录

两种客户端访问方式

 

 

代码见StudyNoteOfCsharp项目。

2、WCF开发步骤

2.1、定义和现实服务协定,在WcfServiceLibrary1服务库项目里

 

 

namespace WcfServiceLibrary1
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        int Add(int a, int b);
        [OperationContract]
        int Multiply(int a, int b);
    }

}
View Code

 

 

namespace WcfServiceLibrary1
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
    public class Service1 : IService1
    {
        int IService1.Add(int a, int b)
        {
            return a + b;
        }
        
        int IService1.Multiply(int a, int b)
        {
            return a * b;
        }
    }
}
View Code

 

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- 部署服务库项目时,必须将配置文件的内容添加到 
  主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
        <endpoint address="" binding="basicHttpBinding" 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" httpsGetEnabled="True"/>
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前设置为 false 
            以避免泄漏异常信息-->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>
View Code

 

此项目里调用wcf服务没有用到上面app.config里的配置,所以用处不大

 

2.2、将wcf服务寄宿到winform程序、console控制台程序、或是web程序里

       寄宿到winform程序里

       winform项目app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <!--下面是加上去的-->
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8081/Service1"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
View Code

 

winform界面

代码如下

namespace WcfServiceWinformHost
{
    public partial class Form1 : Form
    {
        //host的地址和service在app.config里设置了
        ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
        public Form1()
        {
            InitializeComponent();
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Text = "wcf服务监听已经开启";            
            host.Open();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            host.Close();
            this.Text = "wcf服务监听已经停止";
        }
    }
}
View Code

 

但“开始监听”时,在浏览器里输入http://localhost:8081/Service1会看到wcf服务已经启动,客户端程序引用http://localhost:8081/Service1地址的服务就可以。

  寄宿到console控制台

app.config配置如下,但配置是无效的,在Program.cs程序里没有用app.config里的配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1" />
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8081/Service1" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceWinformReference1.IService1"
                name="WSHttpBinding_IService1">
                <identity>
                    <userPrincipalName value="SHENGYU\Administrator" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>
View Code

 

 主程序代码如下:

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Step 1 Create a URI to serve as the base address.
            Uri baseAddress = new Uri("http://localhost:8733/WcfServiceLibrary1/Service1/");

            // Step 2 Create a ServiceHost instance
            ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);

            try
            {
                // Step 3 Add a service endpoint.
                selfHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "Service1");

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

                // Step 5 Start 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();
            }


        }
    }
}
View Code

 

可以看到,宿主程序将wcf服务发布到了http://localhost:8733/WcfServiceLibrary1/Service1/而不是app.config里的http://localhost:8081/Service1,客户端程序要引用 http://localhost:8733/WcfServiceLibrary1/Service1/就能访问服务

 寄宿到web网站上,wcf将寄宿到iis上

此时服务可以写在wcf服务应用程序里

 web.config配置如下

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
        在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>
View Code

 

定义和现实服务协定

namespace WcfServiceWebHost
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        int Subtract(int a, int b);
    }    
}
View Code
namespace WcfServiceWebHost
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
    // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
    public class Service1 : IService1
    {
        public int Subtract(int a, int b)
        {
            return a - b;
        }
    }
}
View Code

 

web运行后的地址为:http://localhost:7234/Service1.svc,在客户端调用时只要引用此地址上的服务就可

3、客户端调用

     console控制台客户端调用console控制台服务宿主程序里的wcf服务

   在console控制台客户端引用服务,服务地址是http://localhost:8733/WcfServiceLibrary1/Service1/

   console控制台客户端程序代码如下:

namespace WcfServiceConsoleClient
{
    class Program
    {
        static void Main(string[] args)
        {   
           ServiceWcfServiceConsoleHostReference1.Service1Client client = new ServiceWcfServiceConsoleHostReference1.Service1Client();
           do
           {
               var a = int.Parse(Console.ReadLine());
               var b = int.Parse(Console.ReadLine());
               var result = client.Multiply(a, b);
               Console.WriteLine("Multiply({0},{1}) = {2}", a, b, result);
           } while (Console.ReadLine() != "exit");
          client.Close();
        }
    }
}
View Code

 

 

运行console控制台宿主程序WcfServiceConsoleHost.exe

运行console控制台客户端程序WcfServiceConsoleClient.exe

     console控制台客户端调用winform服务宿主程序里的wcf服务

   在console控制台客户端引用服务,服务地址是http://localhost:8081/Service1,即winform宿主程序app.config里配置的地址(其实地址也可以像上面console控制台宿主上样写在程序里而不写在app.config里)

console控制台客户端代码如下:

namespace WcfServiceConsoleClient
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceWcfServiceWinformHostReference1.Service1Client client = new ServiceWcfServiceWinformHostReference1.Service1Client();
           do
           {
               var a = int.Parse(Console.ReadLine());
               var b = int.Parse(Console.ReadLine());
               var result = client.Add(a, b);
               Console.WriteLine("Add({0},{1}) = {2}", a, b, result);
           } while (Console.ReadLine() != "exit");
          client.Close();
        }
    }
}
View Code

 

运行winform宿主程序,启动服务

运行console控制台客户端程序WcfServiceConsoleClient.exe

 

 

     console控制台客户端调用web服务宿主程序里的wcf服务


在console控制台上引用web服务宿主端http://localhost:7234/Service1.svc的服务

确保web端开启

console控制台客户端代码如下:

namespace WcfServiceConsoleClient
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceWcfServiceWebHostReference1.Service1Client client = new ServiceWcfServiceWebHostReference1.Service1Client();
           do
           {
               var a = int.Parse(Console.ReadLine());
               var b = int.Parse(Console.ReadLine());
               var result = client.Subtract(a, b);
               Console.WriteLine("Subtract({0},{1}) = {2}", a, b, result);
           } while (Console.ReadLine() != "exit");
          client.Close();
        }
    }
}
View Code

 

运行console控制台客户端程序WcfServiceConsoleClient.exe

 

winform客户端调用winform服务端的wcf服务

winform客户端代码和界面如下

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

        private void button1_Click(object sender, EventArgs e)
        {
            //ServiceWinformHostReference1引用的是WcfServiceWinformHost项目里app.config里baseAddress的地址
            ServiceWinformHostReference1.Service1Client client = new ServiceWinformHostReference1.Service1Client();
            textBox3.Text=client.Add(int.Parse(textBox1.Text), int.Parse(textBox2.Text)).ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ServiceWinformHostReference1.Service1Client client = new ServiceWinformHostReference1.Service1Client();
            textBox3.Text = client.Multiply(int.Parse(textBox1.Text), int.Parse(textBox2.Text)).ToString();
        }
    }
}
View Code

 

运行客户端,调用wcf的加法和乘法方法界面如下

 

总结:wcf步骤为

1、写服务接口和实现服务

2、写宿主程序,可以是console控制台、winform、web等等应用程序,并调用服务类,配置好wcf,可以用app.config或是web.config来配置,也可以写在程序里,记录好配置后的服务url地址

3、启用宿主程序,在浏览器上确保服务url地址能访问

4、写客户端程序,程序引用宿主的服务url地址,调用服务里的方法

 

宿主程序在配置wcf时,可能用以下的代码方式

            Uri baseAddress = new Uri("http://localhost:8733/WcfServiceLibrary1/Service1/");

            // Step 2 Create a ServiceHost instance
            ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);
View Code

 baseAddress用来设置服务的地址,ServiceHost类将地址和服务类关联起来

也可以用config配置文件来配置

<system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8081/Service1"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
View Code

 

然后在程序里直接调用:

//host的地址和service在app.config里设置了
        ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
View Code

 认识wcf中的“A\B\C",A指address,就是配置文件里baseaddress的地址,说明去哪里访问服务,B指binding,说明能用什么方式去访问,如wsHttpBinding,C指Contract描述了Service能提供的各种服务。Contract有四种,包括Service Contract, Data Contract, Fault Contract和Message Contract

posted @ 2015-01-04 14:48  shengyu_kmust  阅读(303)  评论(0编辑  收藏  举报