惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
V
Vulnerabilities – Threatpost
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News | PayPal Newsroom
S
Security Affairs
T
Tor Project blog
P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Security @ Cisco Blogs
H
Heimdal Security Blog
Hacker News: Ask HN
Hacker News: Ask HN
Help Net Security
Help Net Security
U
Unit 42
云风的 BLOG
云风的 BLOG
The Hacker News
The Hacker News
Cisco Talos Blog
Cisco Talos Blog
量子位
F
Full Disclosure
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
有赞技术团队
有赞技术团队
T
Troy Hunt's Blog
P
Privacy & Cybersecurity Law Blog
Forbes - Security
Forbes - Security
人人都是产品经理
人人都是产品经理
L
Lohrmann on Cybersecurity
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Security Blog
Microsoft Security Blog
博客园 - Franky
腾讯CDC
AI
AI
Last Week in AI
Last Week in AI
Latest news
Latest news
Google Online Security Blog
Google Online Security Blog
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
IT之家
IT之家
Martin Fowler
Martin Fowler
Blog — PlanetScale
Blog — PlanetScale
V2EX - 技术
V2EX - 技术
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - Animax!

The Tao of Programming Light weight Framework (AnyBase) -- 通信模块说明 关于WinIO.DLL的键盘输入模拟 Light weight Framework (AnyBase) -- Core 模块说明 开源项目 Light weight Framework (AnyBase) 发布 DB4o的缓存机制 Winfrom界面异步操作的一个解决方法 db4o 研究--性能测试 Asp.net动态数据(Dynamic Data) 笔记一 MVC — 笔记 WF笔记 – Workflow概念 WCF Demo – Http、TCP Host - Animax! LINQ TO SQL 笔记 — 存储过程、并发与事务 WCF笔记 - 绑定 正则表达式[转载整理] - Animax! - 博客园 LINQ 笔记 - LINQ to SQL 基本数据操作 - Animax! LINQ 笔记 - 语法与关键字 LINQ 笔记- Lambda Excel导入SQL - Animax! - 博客园
WCF 笔记
Animax! · 2008-04-05 · via 博客园 - Animax!

WCF 笔记 – 简单使用:

WCF 概念:

    WCF 是 “Windows Communication Foundation ”的缩写,Windows Communication Foundation (WCF) 是一个运行库和一组 API,用于创建在服务与客户端之间发送消息的系统。 它使用相同的基础结构和 API 来创建应用程序,这些应用程序可与同一计算机系统上或驻留在另一家公司内并通过 Internet 访问的系统上的其他应用程序进行通信。

    WCF 通过一种面向服务的新型编程模型简化了关联应用程序的开发。通过提供分层的体系结构,WCF 支持多种风格的分布式应用程序开发。 WCF 通道体系结构在底层提供了异步的非类型化消息传递基元。

WCF体系结构图

      

Contract(契约) :

    在WCF中所有需要向外部服务的方法或对象都需要标明契约属性。

    基本契约有4种:

服务契约(Service Contract) :

指示接口或类在 Windows Communication Foundation (WCF) 应用程序中定义服务协定。

数据契约(Data Contract) :

指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。若要使其类型可序列化,类型作者必须为其类型定义数据协定。

异常契约(Fault Contract):

指定服务操作遇到处理错误时返回的一个或多个 SOAP 错误

消息契约(Message Contract):

定义与 SOAP 消息相对应的强类型类。

简单WCFService创建:

    WCF服务端:

    这里创建一个最简单,以Web形式发布的WCFService,现在这里创建一个“WCF 服务应用程序”名为 “WebWcfServiceA

    项目需要 System.ServiceModel 与 System.Runtime.Serialization 的引用。基本上所有有关于WCF的项目,都会需要到引用这两个组件。

    此项目中有一个接口 IWebWcfServiceA 用于表示WCF公开的方法。

    [ServiceContract]

    public interface IWebWcfServiceA

    {

        [OperationContract]

        string serviceFunction(int value);

    }

         这里接口中的契约属性ServiceContract 用于标明这个接口是公开可调用的。

         方法中的契约属性 OperationContract 用于标明这个方法是公开可调用的。

         除了接口外,还需要一个WCF服务文件 ,在这里命名为“WebWcfServiceA.svc”。

    public class WebWcfServiceA : IWebWcfServiceA

    {

        public string serviceFunction(int value)

        {

            return string.Format("You entered: {0}", value);

        }

    }

         这个类是WCF的主体,它继承于WCF公开的接口并完成接口的功能。

         这里需要注意的是,所有对接口ServiceContract 和服务文件 WebWcfServiceA.svc进行过名称更改的,都需要在配置文件中进行相应的更改。

       在配置文件中的 <system.serviceModel>节里面说明了WCF相关的配置,在这里需要注意的是元素service endpoint service name 属性指名了WCF 服务类的位置;endpoint contract 属性指名了契约接口的位置。

客户端:

         现在为这个简单的WCFService创建一个简单的客户端,控制台程序“WebWcfAClient”。

         最简单创建客户端的办法就是像创建Web Service那样添加一个服务引用,这个服务引用直接指向刚才创建的WebWcfServiceA项目。

         创建成功后,项目会添加一份app.config,此文件记录了关于WCF服务的信息,其中这里需要注意一下的是client 中的 endpointaddress ,这里记录了指向WCF 服务的路径。

         创建这样一个服务引用后,便可以直接调用其中暴露出来的方法。

        static void Main()

        {

            WebWcfServiceA.WebWcfServiceAClient ServiceA = new WebWcfAClient.WebWcfServiceA.WebWcfServiceAClient();

            Console.WriteLine(ServiceA.serviceFunction(0));

            Console.ReadKey();

            ServiceA.Close();

        }

    这种客户端方式的调用,基本和webService的调用相似。

第二种WcfService创建:

    因为公开暴露的方法是在接口上,所以除了使用服务引用的办法来创建客户端引用外,还可以通过使用引用该接口的办法来调用WCF的服务。

    契约接口:

         首先,创建一个接口项目(IWebWcfServiceB)用于服务端和客户端双方的调用:

    [ServiceContract]

    public interface IService

    {

        [OperationContract]

        CompositeType serviceFunction(int value);

    }

    [DataContract]

    public class CompositeType

    {

        [DataMember]

        public string strValue

        {

            get;

            set;

        }

    }

这里的CompositeType类的属性DataContract(数据契约)用于标明此类是用在于WCF服务中提供数据的,并且此类是可以序列化的。

         属性strValue上的DataMember属性标明属性strValue可以序列化。

    服务端:

    服务段只有一个文件WebWcfServiceB.svc

    public class WebWcfServiceB : IService

    {

        public CompositeType serviceFunction(int value)

        {

            CompositeType ct = new CompositeType();

            ct.strValue = string.Format("You entered: {0}", value);

            return ct;

        }

    }

    它基本和WebWcfServiceB.svc一致,只是继承的接口被分离到另外一个项目中。

    客户端:

    客户端需要引用接口IWebWcfServiceB,还需要为接口创建一个代理类,用于调用WCF服务。

    这个接口类可以手工创建,但是你运行打开上述的WebWcfServiceB.svc 文件时候会发现VS提供了一个工具svcutil.exe 来创建这个代理类。

         这里是一个手工写的代理类:

    public partial class ServiceClient : System.ServiceModel.ClientBase<IService>, IService

    {

        public ServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :

            base(binding, remoteAddress)

        {

        }

        public CompositeType serviceFunction(int value)

        {

            return base.Channel.serviceFunction(value);

        }

    }

    [DataContractAttribute]

    public partial class CompositeType : object, System.Runtime.Serialization.IExtensibleDataObject

    {

        public System.Runtime.Serialization.ExtensionDataObject ExtensionData

        {

            get;

            set;

        }

        [DataMemberAttribute]

        public string strValue

        {

            get;

            set;

        }

    }

    需要注意的是这里的命名空间要和公开接口的命名空间一致。

    如果使用工具写出的代码会有更多的实现方法,并且工具将会输出一个名为output.config 的文件,此文件和使用服务引用时添加的配置文件一样。

         代理类的使用如下:

            System.ServiceModel.WSHttpBinding binding = new System.ServiceModel.WSHttpBinding();

            System.ServiceModel.EndpointAddress address =

                new System.ServiceModel.EndpointAddress(new Uri("http://localhost/WebWcfServiceB.svc"));

            ServiceClient ServiceB = new ServiceClient(binding, address);

            CompositeType ct = ServiceB.serviceFunction(0);

            Console.WriteLine(ct.strValue);

            Console.ReadKey();

            ServiceB.Close();

         如果是使用配置文件的,可以直接ServiceClient ServiceB = new ServiceClient() 来读取调用配置文件中的路径。

WCF服务库:

          除了使用上面两种以WCF服务文件为主体,依附IIS的创建方式以外,还可以使用WCF服务库来创建WCF服务。

         直接创建一个WCF服务库,可以看见IDE为你创建了三份文件,一个公开契约的接口,一个控制台应用程序的WCF服务主体,和一份配置文件。

         这个结构和之前创建WCF 服务应用程序基本相同,只不过是主体由svc服务文件变为了控制台的应用程序。

         服务端:

    项目名称:HostWcfServiceA

    [ServiceContract]

    public interface IService

    {

        [OperationContract]

        string serviceFunction(int value);

    }

    public class HostWcfServiceA : IService

    {

        public string serviceFunction(int value)

        {

            return string.Format("You entered: {0}", value);

        }

    }

此服务运行后将会根据配置文件中baseAddress属性的地址来监听,该地址只是用于通信,不能使用浏览器打开。

    客户端:

    创建一个新的控制台程序HostWcfAClient 来作为客户端,客户端对此WCF服务的调用也可以使用服务引用,具体调用和WCF服务文件的方式一样。

服务端除了使用配置文件来配置监听路径外,还可以使用代码来配置监听路径,方法是使用另外一个应用程序来作为服务主机,让客户端调用。

    服务端B

    此服务端B的服务库与项目HostWcfServiceA 的服务库一样,添加多一个控制台应用程序作为服务器:

            Uri baseAddress = new Uri("http://127.0.0.1:55555");

            using (ServiceHost host = new ServiceHost(typeof(HostWcfServiceB.HostWcfServiceB), new Uri[] { baseAddress }))

            {

                BasicHttpBinding binding = new BasicHttpBinding();

                host.AddServiceEndpoint(typeof(HostWcfServiceB.IService), binding, baseAddress);

                host.Open();

                Console.WriteLine("服务已启动");

                Console.Read();

            }

最后声明: 此文只是本人学习WCF中的一点笔记,如有错谬,请指正。

本文源代码下载