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
好了,我们可以正常访问了!!!