传说中的WCF(3):多个协定
我们知道,WCF服务端是先定义服务协定,其实就是一个接口,然后通过实现接口来定义服务类。那么,有一个问题,如果一个服务类同时实现N个接口(也就是有N个协定)呢?结果会如何?
不必猜,我们还是通过实验来说明吧。
首先,参照下面代码写好服务器端,代码中,我写了三个协定,然后一个服务类同时实现它们。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description; namespace Server
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string SayHelloA();
} [ServiceContract]
public interface IService2
{
[OperationContract]
string SayHelloB();
} [ServiceContract]
public interface IService3
{
[OperationContract]
string SayHelloC();
} /// <summary>
/// 实现服务协定接口的服务类
/// </summary>
class MyService:IService1,IService2,IService3
{
static void Main(string[] args)
{
using (ServiceHost host=new ServiceHost(typeof(MyService),new Uri("http://localhost:8001/service")))
{
WSHttpBinding binding = new WSHttpBinding();
binding.Name = "MyBinding";
binding.Security.Mode = SecurityMode.None;
host.AddServiceEndpoint(typeof(IService1), binding, "mysv1");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior); host.Opened += (s, a) => Console.WriteLine("服务已启动。"); try
{
host.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
host.Close();
}
} string IService1.SayHelloA()
{
return "你好,这是第一个服务协定。";
} string IService2.SayHelloB()
{
return "你好,这是第二个服务协定。";
} string IService3.SayHelloC()
{
return "你好,这是第三个服务协定。";
}
}
}
接着你试一下,在客户端引用服务,看看是什么样的?
神了,这是怎么回事呢?为什么客户端引用的服务中只有第一个协定?
还记得刚才的服务器端代码吗?请注意看我框起来的代码。
如果你上图中能找到原因,表明你悟性不错,呵呵。
注意我们添加终结点的时候,AddServiceEndpoint方法的第一个参数我们传了啥玩意儿进去了?是不是只有第一个服务协定的接口?
是啊,这上好理解了,
我们仅仅让服务类实现多个协定的接口是不够的,还要把希望对客户端公开的协定添加为终结点,对,一个协定一个终结点,不添加终结点的协定就不公开。
好了,现在找到原因了,代码知道怎么改了。
using (ServiceHost host=new ServiceHost(typeof(MyService),new Uri("http://localhost:8001/service")))
{
WSHttpBinding binding = new WSHttpBinding();
binding.Name = "MyBinding";
binding.Security.Mode = SecurityMode.None;
host.AddServiceEndpoint(typeof(IService1), binding, "mysv1");
host.AddServiceEndpoint(typeof(IService2), binding, "mysv2");
host.AddServiceEndpoint(typeof(IService3), binding, "mysv3");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior); host.Opened += (s, a) => Console.WriteLine("服务已启动。"); try
{
host.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
host.Close();
}
看看这回达到目的了没?
嘿,这回全有了。
不过,注意啊,在生成的客户端代理类中,是按协定来划分的,也就是说,我有三个协定,在客户端代码中就生成了三个客户端类。
所以,在客户端,我们应该这样调用。
class Program
{
static void Main(string[] args)
{
WS.Service1Client client1 = new WS.Service1Client();
Console.WriteLine(client1.SayHelloA()); WS.Service2Client client2 = new WS.Service2Client();
Console.WriteLine(client2.SayHelloB()); WS.Service3Client client3 = new WS.Service3Client();
Console.WriteLine(client3.SayHelloC()); Console.ReadKey();
}
传说中的WCF(3):多个协定的更多相关文章
- 传说中的WCF(8):玩转消息协定
Message翻译成中文,相信各位不陌生,是啊,就是消息,在WCF中也有消息这玩意儿,不知道你怎么去理解它.反正俺的理解,就像我们互发短信一个道理,通讯的双方就是服务器与客户端,说白了吧,就是二者之间 ...
- 传说中的WCF(5):数据协定(a)
在第4篇中,咱们了解了发送/接收SOAP头,从本篇开头,我们不妨更深入地去探求一下有关WCF中的消息到底是啥玩意儿.WCF庞大而复杂,而从 MSDN文档中,你会看到许多很专业很抽象的东西,你不禁会问, ...
- 传说中的WCF(2):服务协定的那些事儿
上一篇文章中,我们抛出了N个问题:WCF到底难不难学?复杂吗?如果复杂,可以化繁为简吗? 其实,这些问题的答案全取决于你的心态,都说“态度决定一切”,这句话,不知道各位信不信,反正我是信了.首先,敢于 ...
- [转] 传说中的WCF(2):服务协定的那些事儿
上一篇文章中,我们抛出了N个问题:WCF到底难不难学?复杂吗?如果复杂,可以化繁为简吗? 其实,这些问题的答案全取决于你的心态,都说“态度决定一切”,这句话,不知道各位信不信,反正我是信了.首先,敢于 ...
- 传说中的WCF(6):数据协定(b)
我们继续,上一回我们了解了数据协定的一部分内容,今天我们接着来做实验.好的,实验之前先说一句:实验有风险,写代码须谨慎. 实验开始!现在,我们定义两个带数据协定的类——Student和AddrInfo ...
- 传说中的WCF(12):服务器回调有啥用
你说,服务器端回调有啥用呢?这样问,估计不好回答,是吧.不急,先讨论一个情景. 假设现有服务器端S,客户端A开始连接S并调用相关操作,其中有一个操作,在功能上有些特殊,调用后无法即时回复,因为在服务器 ...
- 传说中的WCF(11):会话(Session)
在标题中我加了一个大家都很熟悉的单词——Session,熟吧?玩过Web开发的朋友肯定在梦中都会见到她. 在Web中为什么要会话呢?毕竟每个用户在一个Web应用中可能不止进行一次操作,比如,某二手飞机 ...
- 传说中的WCF(10):消息拦截与篡改
我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过 程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过 ...
- 传说中的WCF(9):流与文件传输
在使用Socket/TCP来传输文件,弄起来不仅会有些复杂,而且较经典的“粘包”问题有时候会让人火冒七丈.如果你不喜欢用Socket来传文件,不妨试试WCF,WCF的流模式传输还是相当强大和相当实用的 ...
随机推荐
- golang的序列与反序列化
golang写backend之类的应用,还是挺方便的...使用encoding/json包时, 必须注意, 在struct定义的属性必须是exported, 否则不会设置值. 例如:type DRol ...
- 第三方登录开发-Facebook
这次这个项目要分别可以使用新浪微博,qq互联以及Facebook和Twitter授权登录 facebook目前只支持oauth2技术,个人理解其工作流程是当用户想访问当前网站,却不想注册账号,此时当前 ...
- (转)android Fragments详解三:实现Fragment的界面
为fragment添加用户界面 fragment一般作为activity的用户界面的一部分,把它自己的layout嵌入到activity的layout中. 一个 要为fragment提供layo ...
- FTP上传文件夹
文件上传类 using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; usi ...
- 008--VS2013 C++ 位图半透明化(另一种显示)
注:主要变化是在下面这张位图上的操作 //全局变量HBITMAP bg, girl;HDC mdc;//起始坐标const int xstart = 50;const int ystart = 20; ...
- OC-通讯录
要求描述:用OC语言完成简易通讯录(实现增删改查)功能.(注:使用MRC) 1.创建AddressBook类. 1)使用字典作为容器,字典的Key值为分组名(姓名首字母),value值为数组,数组中存 ...
- 思维认知-读mindhacks杂记
1. 导语 无意中浏览知乎,搜索到了mindhacks.cn这个个人geek的网址.mindhacks博主本人是牛人程序员一枚,但他的博客主题涵盖的主要内容确是思维改变生活. 博客链接地址:http: ...
- ArtJS(原创)
<script> /* 方法目录: [IE7 8 不支持trim()方法的弥补] [ 终止冒泡] [数字千分位] [js运算的替代方法(js3.3/1.1不等于3浮点计算有bug)] [日 ...
- oracle关于分区相关操作
[sql] view plaincopy 1.查询当前用户下有哪些是分区表: SELECT * FROM USER_PART_TABLES; 2.查询当前用户下有哪些分区索引: SELECT * FR ...
- “我爱淘”冲刺阶段Scrum站立会议4
完成任务: 完成了搜索界面的Activity的编写. 计划任务: 实现数据库的链接,用户可以查到自己需要的书籍的信息. 遇到问题: 数据库的操作,实现查询功能: