zoukankan      html  css  js  c++  java
  • WCF之一

      WCF(Windows Communication Foundation)的概念这里就不多说了,google一下就知道了。

      必须知道的是,WCF的服务是不能孤立的存在的,需寄宿于一个运行的的进程中(我们称之为宿主),为服务指定宿主的过程成为服务寄宿。服务寄宿有两种方式:一种是自我寄宿;另一种是通过IIS将服务寄宿于IIS进程中。

      接下来就先来看看第一种寄宿方式——自我寄宿。

      首先,新建一个空的解决方案,添加如图所示项目

      

    每个项目的描述及项目之间的关系如下:

    • Contracts类库项目,定义服务契约(Service Contract),引用System.ServiceModel程序集;
    • Services类库项目,提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,所以Services具有对Contracts项目的引用;
    • Hosting控制台应用程序(宿主),实现对定义在Services项目中的服务的寄宿,引用Contracts、Services和System.ServiceModel程序集;
    • Client控制台应用程序(客户端),引用System.ServiceModel程序集。

      Tag:有关更多System.ServiceModel,请点击http://msdn.microsoft.com/zh-cn/library/vstudio/system.servicemodel.aspx

      创建服务契约:一般地,通过接口的形式定义服务契约。通过下面的代码,将一个接口ITestWcf定义成服务契约。WCF广泛采用基于自定义特性(Custom Attribtue)的声明式编程模式,我们通过在接口上应用System.ServiceModel.ServiceContractAttribute特性将一个接口定义成服务契约

    using System.ServiceModel;
    
    namespace Contracts
    {
        [ServiceContract]
        public interface ITestWcf
        {
            [OperationContract]
            string HelloWord();
        }
    }

      创建服务:WCF服务TestWcfService定义在Services项目中,实现了服务契约接口ITestWcf,实现了所有的服务操作

    using Contracts;
    namespace Services
    {
        public class TestWcfService : ITestWcf
        {
            public string HelloWord()
            {
                return "Hello Word";
            }
        }
    }

      自我寄宿:在实现寄宿之前,先了解些关键概念。

       WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手        段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成。由于三要素应为首字母分别为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的所有信息,我们可以这样认识终结点的ABC:

      地址(Address):地址决定了服务的位置,解决了服务寻址的问题,意味着标识服务在哪里

      绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等,意味着信息如何传输

      契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。意味着信息具体是什么

      在了解了ABC后,再来看代码:

    using System;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using Contracts;
    using Services;
    
    namespace Hosting
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(TestWcfService)))
                {
                    host.AddServiceEndpoint(typeof(ITestWcf), new WSHttpBinding(), "http://127.0.0.1:9999/testwcfservice");
                    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    {
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); ;
                        behavior.HttpGetEnabled = true;
                        behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/testwcfservice/metadata");
                        host.Description.Behaviors.Add(behavior);
                    }
                    host.Opened += delegate
                    {
                        Console.WriteLine("TestWcfService已经启动,按任意键终止服务!");
                    };
                    host.Open();
                    Console.Read();
                }
            }
        }
    }

      松耦合是SOA的一个基本的特征,WCF应用中客户端和服务端的松耦合体现在客户端只须要了解WCF服务基本的描述,而无须知道具体的实现细节,就可以实现正常的服务调用。WCF服务的描述通过元数据(Metadata)的形式发布出来。WCF中元数据的发布通过一个特殊的服务行为ServiceMetadataBehavior实现。在上面提供的服务寄宿代码中,我们为创建的ServiceHost添加了ServiceMetadataBehavior,并采用了基于HTTP-GET的元数据获取方式,元数据的发布地址通过ServiceMetadataBehavior的HttpGetUrl指定。在调用ServiceHost的Open方法对服务成功寄宿后,我们可以通过该地址获取服务相关的元数据。在IE地址栏上键入http://127.0.0.1:9999/testwcfservice/metadata,你将会得到以WSDL形式体现的服务元数据,部分如图

      当然,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面的代码可以用如下的配置代替

    <?xml version='1.0' encoding='utf-8'?>
    <configuration>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="metadataBehavior">
              <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/testwcfservice/metadata" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service name="Services.TestWcfService" behaviorConfiguration="metadataBehavior">
            <endpoint address="http://127.0.0.1:9999/testwcfservice" binding="wsHttpBinding" contract="Contracts.ITestWcf" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>

    而在Hosting宿主内的代码就精简了许多

    using System;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using Contracts;
    using Services;
    
    namespace Hosting
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(TestWcfService)))
                {
                    //host.AddServiceEndpoint(typeof(ITestWcf), new WSHttpBinding(), "http://127.0.0.1:9999/testwcfservice");
                    //if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    //{
                    //    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); ;
                    //    behavior.HttpGetEnabled = true;
                    //    behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/testwcfservice/metadata");
                    //    host.Description.Behaviors.Add(behavior);
                    //}
                    host.Opened += delegate
                    {
                        Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
                    };
                    host.Open();
                    Console.Read();
                }
            }
        }
    }

      一般对于初学者来说,WCF的配置显得过于复杂,直接对配置文件进行手工编辑不太现实。可以通过VS的工具(Tools)菜单,选择“WCF Service Configuration Editor”子项,开启这样的一个配置编辑器

      客户端调用:在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,如图6所示的添加服务引用的对话会显示出来。在地址栏上键入服务元数据发布的源地址:http://127.0.0.1:9999/testwcfservice/metadata,并指定一个命名空间,点击OK按钮,VS为为你生成一系列用于服务调用的代码和配置。

    客户端代码如下:

    using System;
    using Client.WcfTest;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (TestWcfClient hw=new TestWcfClient())
                {
                    Console.WriteLine(hw.HelloWord());
                }
            }
        }
    }

    当然输出结果就不用贴出来了。

    接下来看第二种方式——IIS进程寄宿

    在原有项目的基础上,添加一个wcf应用程序项目

    打开TestWcfService.svc添加

    然后生成运行TestWcfService,生成部署包后发布IIS

    Tag:这里的配置文件基本和上面的一样,但这里不需要配置终结点地址

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="metadataBehavior">
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service behaviorConfiguration="metadataBehavior" name="Services.TestWcfService">
            <endpoint  binding="wsHttpBinding" contract="Contracts.ITestWcf" />
          </service>
        </services>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
      
    </configuration>

    通过访问http://192.168.0.1/TestWcfService.svc

    如图

    然后在客户端添加服务引用

    客户端代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Client.TestWcf;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (TestWcfClient test = new TestWcfClient())
                {
                    Console.WriteLine(test.HelloWord());
                }
            }
        }
    }

    在发布IIS时,可能会遇到


    这样的问题,解决方法:找到配置文件所在文件夹,单击右键属性,切换到“安全”选项卡,将 IIS-IUSRS 用户组添加到安全列表中,并按需求赋予其权限(我赋予了修改的权限),更改后如下图:

    查看 web.config 的安全权限,如果有此用户组的权限则说明成功,否则退回到根文件夹,打开“安全”选项卡,选中 IIS-IUSRS 用户组,点“高级”打开高级安全设置对话框,选中 IIS-IUSRS 用户组,点击“更改权限”,打开可编辑的高级安全设置对话框,把下图红色区域的复选按钮选上,

    完成以上步骤,如果还不能解决问题,就在 IIS 中选中应用程序,修改应用程序域。(如果没有4.0相应的应用程序域,在vs2010命令提示符下运行aspnet_regiis.exe –i)

  • 相关阅读:
    用css实现网页背景渐变的代码
    表格特效代码 立体表格 圆角表格 变色的单元格
    谷歌地图离线包尝试
    opensoial google社会化网络API
    在自己网站嵌入各大搜索引擎代码
    利用谷歌搜索建立自己的站内搜索引擎
    Jquery学习
    网站备案 ICP备案流程
    了解JavaScript的类和对象
    QeePHP中modules下的模块ACL配置规则
  • 原文地址:https://www.cnblogs.com/DonnyPeng/p/3099451.html
Copyright © 2011-2022 走看看