WCF

1.简介

  WCF(Windows Communication Foundatio:Windows通信框架)是基于微软.NET平台编写的分布式应用的统一编程模型。

  在WCF出现之前,常见的有以下三种分布式技术

    webservice  基于http协议的soap模式

    remoting  常用于tcp模式的二进制传输

    MSMQ   这是一种分布式离线技术,用于业务解耦

  因为分布式技术太多,使用不方便,需要整合,所以WCF应运而生。

  WCF本质就是对上面技术的再次封装。

2.开始我们的WCF之旅

   新建一个控制台应用程序MyFirstWCF

  添加一个WCF服务,命名为TeachService,这样程序会自动添加一下内容,而且App.config也会新增<system.serviceModel>

    

  ITeachService

using System.ServiceModel;

namespace MyFirstWCF
{
    [ServiceContract]//表示这个接口类遵循WCF协定
    public interface ITeachService
    {
        [OperationContract]//表示这个方法是服务协定的一部分,只有添加了以上特性,才能保证接口被WCF运行时获取到
        string GetCourseName(int courseId);//这个方法是我们自己添加的,不使用自动生成的方法,自动生成的已删除
    }
}

  TeachService

namespace MyFirstWCF
{
    public class TeachService : ITeachService
    {
        public string GetCourseName(int courseId)
        {
            return "WCT 通信技术";//做测试而已,不管什么参数,都打印这句话
        }
    }
}

  App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  
  
  
  
  
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="MyFirstWCF.TeachService">
                <endpoint address="" binding="basicHttpBinding" contract="MyFirstWCF.ITeachService">
                  <!--abc的概念-->
                  <!--address【地址】,如果不写,则使用下面的baseAddress【基础地址】,基础地址可以修改-->
                  <!--binding【绑定】,表示通过哪一种通道-->
                  <!--contract【契约】,表示具体使用的接口-->
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8733/MyFirstWCF/TeachService/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
  
  
  
</configuration>

  abc概念可以参考一下图片

    

  Program:

using System;
using System.ServiceModel;

namespace MyFirstWCF
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用ServiceHost启动
            ServiceHost host=new ServiceHost (typeof(TeachService));
            host.Open();
            Console.WriteLine("WCF start...");
            Console.Read();
        }
    }
}

  运行起来,会发生错误

  HTTP 无法注册 URL http://+:8733/MyFirstWCF/TeachService/。进程不具有此命名空间的访问权限(有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkId=70353)。”

  解决方法:

    1)以管理员身份运行vs

    2)以管理员身份运行

      

  结果:

    

    成功运行

3.新建一个客户端

  只是为了演示,我们添加在同一个解决方案里面就可以了

  还是一样,添加一个控制台应用程序TestClientApp

  在引用那里右键添加一个【服务引用】,地址为WCF的地址,因为上面地址为空,所以使用基础地址

    http://localhost:8733/MyFirstWCF/TeachService/

  

  转到的时候,WCF程序必须有在运行,不然就会报错。

  

  成功!命名空间可以自己定义。

  App.config也会添加相应的内容,可以自己看一下,不用修改,就不展示了

  Program如下:

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

namespace TestClientApp
{
    class Program
    {
        static void Main(string[] args)
        {
            MyFirstMCF.TeachServiceClient client = new MyFirstMCF.TeachServiceClient();//TeachService映射到客户端会自动加上Client后缀
            
            string courseName = client.GetCourseName(1);

            Console.WriteLine("我们正在学习"+courseName);

            Console.Read();
        }
    }
}

  结果:

    

  成功获取返回值!

 4.FaultException错误传递

  添加一个可能会报错的函数,这里我们定义一个除法,我们知道,当除数为0,则函数报错

  ITeachService添加:

        [OperationContract]
        int Division(int x, int y);

  TeachService定义这个方法:

        public int Division(int x, int y)
        {
            try
            {
                return x / y;
            }
            catch(Exception ex)//发送错误,用FaultException返回
            {
                throw new FaultException(ex.Message);
            }
        }

  记住,写完后要重新生成一下,然后启动服务

  客户端Program:

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

namespace TestClientApp
{
    class Program
    {
        static void Main(string[] args)
        {
            MyFirstMCF.TeachServiceClient client = new MyFirstMCF.TeachServiceClient();try
            {
                int resu = client.Division(10, 0);
                Console.WriteLine("结果:" + resu);
            }
            catch (Exception ex)
            {
                Console.WriteLine("错误:"+ex.Message);
            }
            Console.Read();
        }
    }
}

  这里,服务端会把错误返回给客户端,客户端直接打印即可。

 5.三种操作

  1)请求响应操作

    默认情况下,服务契约中的操作都属于“请求响应”操作,也就是上述的所有方法都是一个请求响应操作

  2)单程操作(One-Way)

    不需要服务端给出响应,即客户端发送消息,并且得到服务端确认后,就理解结束本次操作调用的模式

    如:

      客户端调用服务端的Void方法(方法名字上一般得加上IsOneWay=true)

        [OperationContract(IsOneWay = true)]
        void SayHello();

  3)双程操作

6.binding

 

7.在IIS上部署wcf

  首先,我们新建一个web程序,在程序里面添加wcf服务

    

  web程序对应的wcf服务是一个网站,生成的配置文件也和控制台应用程序不一样

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

  在这里我们可以不管他,直接运行网站

     

  执行结果:

    

  然后,在别的程序添加服务引用的时候使用的是上面的链接

  ===》进入主题:如何把WCF部署到IIS

  在IIS新建一个站点,然后把这个网站程序发布过去,运行

  找到对应的WCF程序入口(就是上面的链接换上站点对应的端口号)

  我们会发现程序报错,访问不了WCF服务

  解决方法:

    

    1)添加MIME类型

      扩展名:.svc

      MIME类型 :application/octet-stream

      

    2)找到处理程序映射,添加托管处理程序 

      请求路经:*.svc

      类型:System.ServiceModel.Activation.HttpHandler

      名称:svc-Integrated

      

   好了,我们可以正常访问了!!!

原文地址:https://www.cnblogs.com/wskxy/p/9435300.html