C#之WCF入门1—简单的wcf例子

第一步:创建一个空的解决方案,新建一个WCF服务应用程序项目(使用默认名字) 来模拟服务端,新建一个控制台应用程序项目(名称改为 ConsoleApp)来模拟客户端。

第二步:简单分析WcfService_1项目,该项目内容如下:

一句话总结:这个项目模拟服务器端,Service1.svc文件封装的就是提供给客户端的服务引用,Service1.svc.cs文件里是服务引用的具体实现。但这里因为Service1.svc.cs文件里的主要内容——Service1类是继承于 IService1.cs文件里的 IService1接口,所以重头戏分了一半给IService1.cs文件。

首先看IService1.cs文件,从名字上可以看得出这个是接口文件,里面定义了了一些接口,接口声明了一些方法。我在里面添加两个类 public class Student1 、 public class Student2 和一个方法 Student1 StudentWriteName(string name)用作测试。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService_1
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: 在此添加您的服务操作

        //新增方法
        [OperationContract]
        Student1 StudentWriteName(string name);
    }

    // 使用下面示例中说明的数据约定将复合类型添加到服务操作。
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

    #region 新增stu类

    [DataContract]
    public class Student1
    {
        string name;

        [DataMember]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    public class Student2
    {
        string name = "张三";

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

    }

    #endregion
}

上面这段代码要注意以下几方面:

2-1、服务契约

接口IService1前面加了 [ServiceContract] ,意思是把这个接口(包括继承这个接口的类)声明为服务契约,服务契约是对客户端而言的,就是这个接口 暴露 在客户端面前,就是让客户端可得见这个接口。但看得见接口不表达可以看得见接口里声明的方法,这是两回事(原因很简单,就算接口是可见的,但里面的方法也有一些是可见另一些不可见的嘛),如果想把方法也声明为对客户端可见的,得在声明方法的签名加 [OperationContract],这也叫服务契约。总结:服务契约有两种,[ServiceContract]是声明接口、类对客户端可见的,[OperationContract]是具体声明类里的那些方法对客户端可见。

2-2、数据契约

     接口自带的类CompositeType 和我们自定义的类Student1、Student2 前面都加了 [DataContract] ,意思是把这个类声明为数据契约,这样子客户端就可以用这个类去定义变量了。这里说的类和上面说的类所指的具体内容稍稍有点不同,上面的类偏向于可以调用类中的方法,这里的类偏向于指作为一种类型(就像int string 等类型),可以用来定义变量。类对客户端可见,但类中的字段、变量则不一定(原理和上面说的一样),要在想暴露在客户端的字段、变量前面加 [DataMember] 。但不能在方法(如构造函数)前面加[DataMember],因为函数只能声明为服务契约嘛(加[OperationContract]),而服务契约只能在 [ServiceContract] 下面声明。总结:数据契约有两种,[DataContract]是声明类或结构的,[DataMember] 是声明类或结构中具体的字段或属性(推荐用属性)对客户可见。

再来看Service.svc.cs文件。可以看到里面只是定义了一个继承 IService1接口的类 Service1,主要内容就是实现IService1接口里声明的方法。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService_1
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
    // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        #region 新增方法

        public Student1 StudentWriteName(string name)
        {
            Student1 s1 = new Student1();
            s1.Name = name;

            return s1;
        }

        #endregion
    }
}

里面的定义的类或者是实现的方法前面都没有加什么 [ServiceContract][OperationContract] 声明,因为类继承的接口已经声明了,所以类就不用再声明[ServiceContract] 了,实现接口的方法 也不用加[OperationContract]

可能大家有一个问题,那就是在这个类里添加自己的方法行不?答案是可以,但没意义。因为在这个类作为服务端(可以这么认为),里面的方法就是为了给客户端使用的,那么就要在声明的方法前加[OperationContract],但只有加了 [ServiceContract]属性的类里的方法才能那样子,又因为类是继承了一个具有 [ServiceContract]属性的接口了的,所以这个类就不用再加 [ServiceContract]属性了(已经有了),一句话,就是在 继承了 实现了服务契约的接口 的类里没必要。添加自己的方法。要加就先加在接口里。

当然,如果你不用接口(可以不用接口的,用接口只是为了更面向对象而已),直接在类里定义服务契约的话,直接把接口里的那些[ServiceContract] 、 [OperationContract] 照搬过来就行了。

第三步:分析ConsoleApp项目

一句话总结:红框框里的那个东西叫服务引用,也就是客户端,也就是靠它才能调用服务端提供的方法和自定义类型。添加方法如下:

右键点击 ConsoleApp项目,选择 添加服务引用(使用默认名称),会弹出一方框:

点右边的 “发现”,就会检索出发现的服务并显示在左边,并把地址也显示出来。点左边 服务里发现的服务左边的三角形,一级级打开,赫然发现里面就是 Service1 类,再往下就是 Service1类继承的接口 IService1 !对应右边就是该服务提供给客户端调用的方法!

打开ConsoleApp里的Program.cs文件,里面代码很简单,定义一个student1类的变量,然后获取她的一个属性值并输出。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp_1
{
    class Program
    {
        static void Main(string[] args)
        {
            //定义通信管道 client,就是通过它来调用服务端提供的方法
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
            string str = client.GetData(1);
            Console.WriteLine(str);

            //服务端提供给客户端使用的类
            ServiceReference1.Student1 stu1 = new ServiceReference1.Student1();
            stu1 = client.StudentWriteName("张三");
            Console.WriteLine("我的姓名:"+stu1.Name);

            Console.ReadKey();

        }
    }
}

ServiceReference1(其实是一个命名空间)就是刚才添加的服务引用的名称。当输入ServiceReference1.的时候,后面就会出现智能感知到的这个命名空间能引用的类型、接口等内容(有时候没有出现如你所愿的类型时,右键点WcfService1项目选择重新生成,然后右键点ConsoleApp项目的ServiceReference1选择更新服务引用,这个很容易忘掉,每对服务端做了什么修改都要这么来一下)。图如下:

里面还定义了一个什么通信管道的东西,这个东西估计就是把服务端提供的可工客户端引用的方法封装成了一个类,通过这个类就可以调用那些方法了,详情见代码。

最后按F5运行,没什么问题吧?没有输出?这是正常的,如果你想看到输出结果,可以先对Str属性赋值(stu.Str = "123";)。嘿嘿,那就算完成了。

转载:http://www.cnblogs.com/zouzf/archive/2012/02/28/2370667.html

最后还有两个问题:

1、在IService1接口里自定义了两个类 Student1 和Student2,为什么输入ServiceReference1.后的智能感知里只有 student1类型而没有student2类型?因为在IService1接口里有一个方法 public Student1 StudentWriteName(string name);,这个方法的返回值是 studnet1类型,这就是差别。。。。就是你想在客户使用在服务端里自定义的类型,除了用[DataContract]声明之外,还要有一个服务契约(方法)的返回值是这个类型的。至于为什么,我也不知道。。求答案

2、student1类里的Str属性有一个Get{return str;}方法,而字段str是有默认值的,为什么在Program.cs里定义了一个student1类的变量后,获取Str属性的值并输出时是空白?也就是说属性的默认值发生了丢失!为什么?不知道,求答案。。。

 

时间: 2024-10-31 01:55:41

C#之WCF入门1—简单的wcf例子的相关文章

WCF入门(十)---WCF事务

事务处理在WCF(Windows Communication Foundation)是一套遵循一些性质,统称为ACID的操作.这里,如果一个操作出现故障,整个系统就会自动失败.如网上订单生成,就可能使用事务.下面的例子可以帮助理解事务的过程中更简单的术语. 例子 假设一台液晶电视是您从在线商店订购,你会通过信用卡支付的金额.当输入必要的信息来下订单,同时出现两个操作.一个特定的量被从您的银行账户中扣除,第二是供应商贷记相同.两个操作必须以有一个成功的事务成功执行. WCF事务属性 WCF事务有以

WCF入门(九)--WCF实例管理

这组由Windows通讯基础(WCF)结合一组消息(客户端请求)服务实例所采用的技术被称为实例管理.一个完全由三种类型实例激活支持WCF,它们如下所述. 1.每个调用服务 每次调用服务是Windows通讯基础的默认实例激活模式.当一个WCF服务配置为每个调用服务,一个CLR对象是时间跨度客户调用或请求进行创建. CLR代表公共语言运行库,并在WCF服务实例. 在每个调用服务,每一个客户端请求实现专用消耗相同的内存并且新的服务实例较少,相较于其他类型的实例激活.必需有InstanceContext

[theano]入门-一个简单训练的例子

#!/usr/bin/env python # coding=utf-8#这个例子相对来讲比较简单可以作为训练编程的模板 import numpy import theano import theano.tensor as T rng = numpy.random N = 400 feats = 784 D = (rng.randn(N, feats), rng.randint(size=N, low=0, high=2)) training_steps = 10000 # Declare Th

java入门---简介&简单输出小例子&开发前准备

    Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称.由James Gosling和同事们共同研发,并在1995年正式推出.Java分为三个体系: JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版) JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版) JavaME(J2ME)(Java 2 Plat

WCF入门简单教程(图文) VS2010版

在这个例子中我们将使用VS 2010 创建一个WCF服务,其中会了解 [DataContract] [ServiceContract] 等特性.  内置的 WCFSVCHost ,并使用"WCF测试客户端"来测试我们创建的服务. 注意下面的所有类.接口及方法都添加了public 的访问级别. 一,建立一个WCF服务库 创建一个WCF服务库项目 在解决方案中会自动为我们生成两个类文件"IService1.cs"和"Service1.cs". 这两个

【转】WCF入门教程六[一个简单的Demo]

一.前言 前面的几个章节介绍了很多理论基础,如:什么是WCF.WCF中的A.B.C.WCF的传输模式.本文从零开始和大家一起写一个小的WCF应用程序Demo. 大多框架的学习都是从增.删.改.查开始来学习的,我们学习WCF也是一样的.从简单来看(不包括安全.优化等相关问题),WCF的增删改查和WebForm相差无几.WCF只是把具体"实现"写在"Service端",而"调用"放在了"Client端".觉得有帮助别忘了点个赞哈,

无废话WCF入门教程六[一个简单的Demo]

wcf技术交流,同学习,同进步. 群号:89718412 一.前言 前面的几个章节介绍了很多理论基础,如:什么是WCF.WCF中的A.B.C.WCF的传输模式.本文从零开始和大家一起写一个小的WCF应用程序Demo. 大多框架的学习都是从增.删.改.查开始来学习的,我们学习WCF也是一样的.从简单来看(不包括安全.优化等相关问题),WCF的增删改查和WebForm相差无几.WCF只是把具体“实现”写在“Service端”,而“调用”放在了“Client端”.觉得有帮助别忘了点个赞哈,谢谢哦~ 二

WCF 入门 (17)

前言 看的是入门视频,就希望培养一个学习的习惯吧. 前段时间看了微软的SurfaceBook的视频,被惊艳到了,但是我没钱买啊... 第17集 WCF中未经处理的异常 Unhandled exceptions in WCF 这集讲一下WCF中服务端如果出现异常会怎么样.还是用上集的demo. 服务端代码: public class CalculatorService : ICalculatorService { public double Divide(int numerator, int de

WCF入门教程

无废话WCF入门教程一[什么是WCF] wcf问题有问必答,欢迎加群: 一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NET Framework 3.0 开始引入. WCF的最终目标是通过进程或不同的系统.通过本地网络或是通过Internet收发客户和服务之间的消息. WCF合并了Web服务..net Remoting.消息队列和Enterpris