我所理解的WCF-数据契约(Data Contract)

“数据协定(Data Contract)”是在服务与客户端之间达成的正式协议,用于以抽象方式描述要交换的数据。也就是说,为了进行通信,客户端和服务不必共享相同的类型(1.此处相同的类型指的是什么?),而只需共享相同的数据协定。 数据协定为每个参数或返回类型精确定义为进行交换而序列化(转换为 XML)哪些数据。
一、数据协定基本知识
默认情况下,Windows Communication Foundation (WCF) 使用称为数据协定序列化程序的序列化引擎对数据进行序列化和反序列化(与 XML 进行相互转换)。
必须为所创建的新复杂类型,定义数据协定以便可以进行序列化。 正常情况下可通过将 DataContractAttribute 属性应用到该类型来完成该任务。 可以将此属性应用到类、结构和枚举。 然后必须将 DataMemberAttribute 属性应用到数据协定类型的每个成员,以指示这些成员为数据成员,即应进行序列化
看个例子:

上面的示例演示,如何通过将 DataContractAttributeDataMemberAttribute 属性应用于类及其成员来创建
 MyTypes.PurchaseOrder 类型的数据协定。

需要注意的:
a.数据协定是使用“选择性加入”编程模型设计的;未用 DataMemberAttribute 属性显式标记的任何内容均不序列化。(个人认为是Data Contract与外界数据的一种协议)

b.可以将 DataMemberAttribute 属性应用于字段、属性和事件

c.成员可访问性级别(internal、private、protected 或 public)对数据协定无任何影响。(相互独立)

d.如果将 DataMemberAttribute 属性应用于静态成员,则将忽略该属性。

e.在序列化期间,为属性数据成员调用 property-get 代码来获取要序列化的属性的值。(GET索引器起到获取值的作用)

f.在反序列化期间,首先创建一个未初始化的对象,而不在该类型上调用任何构造函数。 然后反序列化所有数据成员。

g.在反序列化期间,为属性数据成员调用 property-set 代码,将属性设置为要反序列化的值。

h.对于将要生效的数据协定,它必须能序列化其所有数据成员。

i.泛型类型的处理方式与非泛型类型完全相同。 (这一点做的真不错)
写的很零碎,可能会有一种云里雾里的感觉.下面,我会写出一段真实的case.这个case将使您会得到一个正在运行的服务,以及一个可以调用该服务操作的客户端.
本例jason准备用两部分主题来完成:
1.编写server程序
    1.1:如何使用协定,定义服务?
    1.2:如何实现服务?
    1.3:如何在代码中配置服务、承载服务和运行服务

2.编写client程序
    2.1:如何创建客户端代理?
    2.2:如何配置客户端应用程序?
    2.3:如何创建和使用可以访问服务功能的客户端

带着这些问题,我们继续......
在软件工程领域,我们设计软件的架构,到目前为止,主流的还是C/S、B/S。早期的开发模式,c/s占据主导地位.那么,我就以此模式入手.
创建基本 WCF 服务时,第一项任务就是,创建与外界共享的服务协定,并在其中描述如何与该服务进行通信。 此协定指定访问服务所提供的操作,以及必需的消息的集合和结构.我们可以通过创建定义输入和输出类型的接口来执行此操作.
那么,如何通过接口来创建WCF的契约呢?(注:Contract的叫法不同,本文仅称为:契约)
请看例子:
        

创建接口之后,下一步就是实现接口.我们知道,接口是把隐式的公共方法和属性组合起来,以封装 特定功能的一个集合。一旦实现了接口,类就可以支持接口所指定的所有属性和成员.ok.那就上我们看看,如何用类来实现WCF服务契约!

using System;
using System.ServiceModel;
namespace Microsoft.ServiceModel.Samples
{
    // 定义服务契约.
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }

    // Step 1: 定义一个类,来实现服务契约接口ICalculator.
    public class CalculatorService : ICalculator
    {
        // Step 2: 实现服务功能
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            // 添加数据到应用程序控制台输出
            Console.WriteLine("Return: {0}", result);
            return result;
        }
        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            Console.WriteLine("Received Subtract({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            Console.WriteLine("Received Multiply({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            Console.WriteLine("Received Divide({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
    }
}
创建和实现了服务协定后,创建 WCF 服务的下一步是运行该服务。运行服务由三个步骤组成:配置、承载和打开服务
哈哈.终于到了最激动人心的时刻!
    运行基本的WCF 服务。这个过程应包含以下步骤: 
        Step1.为服务创建基址。
        
Step2.为服务创建服务主机。
        
Step3.启用元数据交换。
        
Step4.打开服务主机
代码如下:

    class Program
    {
        static void Main(string[] args)
        {

            // Step 1 为服务的基址创建 Uri 实例。 此 URI 指定 HTTP 方案、本地计算机、端口号 8000,以及服务协定中为服务命名空间指定的服务路径
            Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

            // Step 1 创建一个新的 ServiceHost 实例以承载服务。必须指定实现服务协定和基址的类型.
            ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
            try
            {
                // Step 3 添加公开服务的终结点。 为此,必须指定终结点公开的协议、绑定和终结点的地址.
                selfHost.AddServiceEndpoint(
                    typeof(ICalculator),
                    new WSHttpBinding(),
                    "CalculatorService");

                // Step 4 启用元数据交换.为此,必须添加服务元数据行为。 首先创建一个 ServiceMetadataBehavior 实例,将 HttpGetEnabled 属性设置为 true,然后为服务添加新行为.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                // Step 5 打开 ServiceHost 并等待传入消息.按 Enter 键时,关闭 ServiceHost。
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // 停止the ServiceHostBase服务
                selfHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }
        }
    }
}

posted @ 2008-05-20 21:08  jason wei  阅读(1135)  评论(0编辑  收藏  举报