zoukankan      html  css  js  c++  java
  • WCF学习笔记(基于REST规则方式)

    一、WCF的定义

    WCF是.NET 3.0后开始引入的新技术,意为基于windows平台的通讯服务。

    首先在学习WCF之前,我们也知道他其实是加强版的一个面向服务(SOA)的框架技术。

    如果熟悉WebService就会知道WebService是基于XML+XSD,SOAP和WSDL三大技术,当然他也是采用HTTP协议的通信,严格来说WebService是一种面向服务开发的标准。而ASP.NET WebService则是微软平台下的服务。

    WCF其实一定程度上就是ASP.NET Web Service,因为它支持Web Service的行业标准和核心协议官方的说法WCF它整合了.Net平台下所有的和分布式系统有关的技术,如Enterprise Sevices(COM+).Net Remoting、Web Service(ASMX)、WSE3.0和MSMQ消息队列。以通信(Communiation)范围而论,它可以跨进程、跨机器、跨子网、企业网乃至于 Internet;以宿主程序而论,可以以ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host)。

    WCF可以实现WebService的功能,即WCF实现了对SOAP的直接支持。然后WCF也支持基于REST协议的通信,REST严格说不是一个协议,但是定义了使用服务访问资源的几条规则。支持REST的Web服务是基于HTTP协议和REST规则的简单服务。

    REST规则按照3个类别来定义,1.可以用简单的URI访问的服务,2.支持MIME类型,3.使用不同的HTTP方法。支持MIME类型,就可以从服务中返回不同的数据格式,如普通的XML、JSON等。

    REST规则是基于HTTP请求的四个方法的:GET()方法--从服务中返回数据,POST()方法--创建一个新的数据源,PUT()方法--更新服务端,DELETE()方法--删除数据资源。

    二、WCF项目实例

    1)首先我们定义服务契约,建立一个类库项目Service.Interface,其要引用的链接库如下:

    然后定义了一个数据契约类Employee.cs,注意此处的几个特定特性的写法,这些特性也就规定了他是一个数据契约类,数据契约类是为其他的契约提供数据支持的基本类。

    然后是创建一个服务契约接口类IEmployeesService.cs,和基于SOAP的服务契约定义不同,我们无需在相应的操作方法上面应用OperationContractAttribute特性,但是应用在接口/类上的ServiceContractAttribute特性仍是必需的。在这里替换OperationContractAttribute特性的分别是WebGetAttribute和WebInvokeAttribute,它们均定义在System.ServiceModel.Web程序集中。

    2)创建寄宿服务,添加一个控制台程序Service

    其中在控制台程序Service中我们定义了如下一个实现了契约接口IEmployeesService的服务类型EmployeesService。

     public class EmployeesService : IEmployeesService
        {
            private static IList<Employee> list = new List<Employee>()
            {
                new Employee(){Id="001",Name="张三",Department=".NET部",Grade="1"},
                new Employee(){Id="002",Name="李四",Department="JAVA部",Grade="2"},
                new Employee(){Id="003",Name="王五",Department="PHP部",Grade="3"},
            };
            public IEnumerable<Employee> GetAll()
            {
                return list;
            }
    
            public Employee Get(string id)
            {
                Employee employee = list.FirstOrDefault(e => e.Id == id);
                if (employee == null)
                {
                    //提示没有找到
                }
                return employee;
            }
    
            public void Create(Employee employee)
            {
                list.Add(employee);
            }
    
            public void Update(Employee employee)
            {
                this.Delete(employee.Id);
                list.Add(employee);
            }
    
            public void Delete(string id)
            {
                Employee employee = this.Get(id);
                if (employee != null)
                {
                    list.Remove(employee);
                }
            }
        }
    }

    接下来我们在App.config中通过自我寄宿的方式对上面定义的EmployeesService服务进行寄宿,下面是相应的配置。我们为寄宿的服务添加了唯一一个终结点,并简单地指定了其ABC三要素。和我们之前配置的终结点不同的是,在这里我们采用的绑定类型为WebHttpBinding。

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
      <system.serviceModel>
        <services>
          <service name="Service.EmployeesService">
            <endpoint address="http://127.0.0.1:123/employees"
            binding="webHttpBinding"
              contract="Service.Interface.IEmployeesService"/>
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    

      最终我们通过如下的程序进行服务的寄宿。之前我们总是使用基于服务类型创建的ServiceHost进行服务寄宿,在这里我们使用的是ServiceHost它的子类WebServiceHost

    3)服务的调用

    由于我们寄宿的服务完全是基于Web的,所以和普通的Web站点没有本质的区别。由于EmployeesService服务的GetAll和Get操作支持HTTP-GET请求,所以我们完全可以在浏览器中针对操作的地址发起请求,而返回的数据可以直接显示在浏览器上。下图所示的是通过浏览器调用GetAll操作(http://127.0.0.1:123/employees/all)得到的结果,我们可以看到所有员工的列表以XML的形式返回,当然前提是先启动Service程序再在浏览器访问数据:

    注意:如果你的系统是Win7,如果运行Service程序的时候报了HTTP无法注册URL进程的错误,此处需要用管理员权限运行Visual Studio工具。

    我们也可以通过浏览器调用Get操作并直接通过在地址中指定员工的ID(http://127.0.0.1:123/employees/001)并得到以XML表示的基于相应员工的信息。下图所示XML正式ID为001的Employee对象序列化后的结果。

    上面我们演示了通过浏览器以HTTP-GET方式请求操作地址的方式从而直接将返回结果呈现出来,现在我们来演示如何使用通过ChannelFactory<TChannel>创建的服务代理进行服务调用。

    新建一个控制台程序Client:

    配置App.config文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
      <system.serviceModel>
        <behaviors>
          <endpointBehaviors>
            <behavior name="webBehavior">
              <webHttp />
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <client>
          <endpoint name="Service.EmployeesService"
         address="http://127.0.0.1:123/employees"
        behaviorConfiguration="webBehavior"
         binding="webHttpBinding"
        contract="Service.Interface.IEmployeesService"/>
        </client>
      </system.serviceModel>
    </configuration>
    

      如上面的配置片断所示,我们定义了一个与服务端相匹配的客户端终结点,该终结点上应用了一个WebHttpBehavior终结点行为。WebHttpBehavior可以说是整个Web HTTP编程模型的核心,绝大部分针对Web的支持都是通过该行为实现的。实际上服务端终结点通过WebServiceHost应用了这个终结点行为。

    最后是调用:

    static void Main(string[] args)
            {
                using (ChannelFactory<IEmployeesService> channelFactory = new ChannelFactory<IEmployeesService>("Service.EmployeesService"))
                {
                    IEmployeesService proxy = channelFactory.CreateChannel();
    
                    Console.WriteLine("所有员工列表:");
                    Array.ForEach<Employee>(proxy.GetAll().ToArray(), employee => Console.WriteLine(employee));
    
                    Console.WriteLine("
    添加一个新员工(004):");
                    proxy.Create(new Employee
               {
                   Id = "004",
                   Name = "赵六",
                   Grade = "G9",
                   Department = "行政部"
               });
                    Array.ForEach<Employee>(proxy.GetAll().ToArray(), employee => Console.WriteLine(employee));
    
                    Console.WriteLine("
    修改员工(004)信息:");
                    proxy.Update(new Employee
                    {
                        Id = "004",
                        Name = "赵六2",
                        Grade = "G11",
                        Department = "销售部"
                    });
                    Array.ForEach<Employee>(proxy.GetAll().ToArray(), employee => Console.WriteLine(employee));
                    Console.WriteLine("
    删除员工(004)信息:");
    
                    proxy.Delete("004");
                    Array.ForEach<Employee>(proxy.GetAll().ToArray(), employee => Console.WriteLine(employee));
                    Console.Read();
                }
            }
    

      

    从编程角度来看,我们采用与SOAP服务完全一样的服务调用方式,那么如何反映出服务调用基于Web的本质呢?首先,之前我们能够通过浏览器访问GetAll和Get两个操作可以证明这两个服务操作是基于HTTP-GET的,返回的数据直接以单纯的XML返回,并没有封装成SOAP。为了证明Create、Update和Delete也是完全基于Web的,我们可以通过Fiddler来分析HTTP请求的内容。

  • 相关阅读:
    应用文档iOS, 在应用之间共享文档。
    项目范围项目管理项目范围管理
    网站教程一些学习网站
    布局文件Android ListView入门知识各种Adapter配合使用
    随波逐流希望2013年半年小总结(复杂艰难的半年)
    安全微软微软安全新闻聚焦双周刊第三十二期
    对象类《大话设计模式》部分模式总结(一):
    循环跳转JAVA Continue实例详解
    节点程序寻找链表倒数第k个节点
    box2d编译
  • 原文地址:https://www.cnblogs.com/yk123/p/4634653.html
Copyright © 2011-2022 走看看