客户端发送请求给服务端,服务端根据请求消息把消息转发给对应的终结点。这里面有个消息筛选机制,如果请求消息中带有地址报头相关信息,则会用地址报头匹配当前的所有终结点。所以默认情况下客户端和服务端的地址报头信息一致才可以正常通信。

AddressHeader地址报头是一个抽象类,并且没有构造方法。创建AddressHeader对象需要用到内部静态方法CreateAddressHeader。

public static AddressHeader CreateAddressHeader(string name, string ns, object value);

在WCF请求消息序列化后,AddressHeader也会被列化,其对应的XML节点描述为:值:name,命名空间:ns,结点名称:value。

下面是一个示例演示:

服务端代码:

using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace hostAddressHeader
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(mywcf.CalculatorService)))
{
AddressHeader header1=AddressHeader.CreateAddressHeader("kk","www.kk.com","kkname");
EndpointAddress endpointaddress = new EndpointAddress(new Uri("http://localhost:8899"),header1);
ServiceEndpoint endpoint = new ServiceEndpoint(
ContractDescription.GetContract(typeof(mywcf.ICalculatorService)),
new WSHttpBinding(),
endpointaddress);
host.AddServiceEndpoint(endpoint);
host.Opened+=delegate{Console.WriteLine("Service Start!!");};
host.Open();
Console.ReadLine();
}
}
}
}

上述代码首先创建了一个AddressHeader对象,并将AddressHeader对象放入EndpointAddress。EndpointAddress可以有多个地址报头信息,这里只放入一个。

客户端代码:

using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace clientAddressHeader
{
class Program
{
static void Main(string[] args)
{
AddressHeader header1=AddressHeader.CreateAddressHeader("kk","www.kk.com","kkname");
ServiceEndpoint endpoint=new ServiceEndpoint(
ContractDescription.GetContract(typeof(mywcf.ICalculatorService)),
new WSHttpBinding(),
new EndpointAddress(new Uri("http://localhost:8899"),header)
);
ChannelFactory<mywcf.ICalculatorService> factory=new ChannelFactory<mywcf.ICalculatorService>(endpoint);
mywcf.ICalculatorService client=factory.CreateChannel();
Console.WriteLine(client.Add(1, 2) + "");
}
}
}

客户端使用信道工厂进行创建信道,使用了与服务端相同的报头信息。服务端运行后,再运行客户端能正常访问。

客户端如果没有在EndpointAddress上指定报头,也可以通过OutgoingMessageHeaders直接在消息上添加报头信息。

 static void Main(string[] args)
{
AddressHeader header = AddressHeader.CreateAddressHeader("kk", "www.kk.com", "kkname");
mywcf.ICalculatorService client = ChannelFactory<mywcf.ICalculatorService>.CreateChannel(new WSHttpBinding(), new EndpointAddress("http://localhost:8899"));
using (OperationContextScope scope = new OperationContextScope(client as IContextChannel))
{
OperationContext.Current.OutgoingMessageHeaders.Add(header.ToMessageHeader());
Console.WriteLine(client.Add(1, 2) + "");
}
}

若将客户端的报头地址改成如下:

  AddressHeader header1=AddressHeader.CreateAddressHeader("kd","www.kk.com","kkname");

会引发EndpointNotFoundException异常,因为服务端和客户端地址报头信息不一致,使用默认的消息筛选机制无法找到对应的终结点。

如果不想修改客户端地址报头,又想要避免这个错误,可以修改服务行为的消息筛选机制。筛选机制AddressFilterMode有3种,Exact,Predix,Any。

Exact是默认的筛选机制,要求客户端与服务端的地址报头精确匹配。Predix是前缀匹配,Any是任意匹配。将服务行为的AddressFilterMode 修改成任意匹配,即使客户端与服务端的地址报头不一致也可以访问了。AddressHeader与安全的作用不大,真正的作用是辅助寻址。因为客户端通过wsdl是可以获取到服务端完整的报头信息。

修改如下:

[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]
public class CalculatorService : ICalculatorService {
  public int Add(int x, int y)   {
    return x + y;
  }
}

WCF中的AddressHeader作用的更多相关文章

  1. 在 WCF 中使用高效的 BinaryFormatter 序列化

    本文将定义一个 WCF 终结点行为扩展,以在 WCF 中使用更高效的 BinaryFormatter 进行二进制序列化,并实现对是否使用传统二进制序列化功能的可配置. 介绍 实现步骤 使用方法 效果 ...

  2. 游刃于MVC、WCF中的Autofac

    为了程序的健壮性.扩展性.可维护性,依赖抽象而不是具体实现类等等,于是我选择了Autofac依赖注入容器 就是这个工厂来降低耦合.之前买东西是自己去超市,现在呢 我需要什么东西,他们给送过来直接拿到了 ...

  3. 我的WCF之旅(3):在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  4. WCF技术剖析之十一:异步操作在WCF中的应用(上篇)

    原文:WCF技术剖析之十一:异步操作在WCF中的应用(上篇) 按照操作执行所需的资源类型,我们可以将操作分为CPU绑定型(CPU Bound)操作和I/O绑定型(I/O Bound)操作.对于前者,操 ...

  5. [No0000126]SSL/TLS原理详解与WCF中的WS-Security

    SSL/TLS作为一种互联网安全加密技术 1. SSL/TLS概览 1.1 整体结构 SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下: SSL:(Secure Socket La ...

  6. 在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  7. WCF中的AsyncPattern

    WCF中的AsyncPattern   (系列博文源自 http://pfelix.wordpress.com/,由笔者翻译并整理,转载请注明) 在wcf 的 service contract中, 服 ...

  8. web.xml中load-on-startup的作用

    如下一段配置,熟悉DWR的再熟悉不过了:<servlet>   <servlet-name>dwr-invoker</servlet-name>   <ser ...

  9. WCF中,通过C#代码或App.config配置文件创建ServiceHost类

    C# static void Main(string[] args) { //创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:808 ...

随机推荐

  1. console使用技巧

    http://heikezhi.com/yuanyi/10%E4%B8%AAchrome%20console%E5%AE%9E%E7%94%A8%E5%B0%8F%E6%8A%80%E5%B7%A7 ...

  2. 【题解】 BZOJ4548 小奇的糖果

    本文同步在学弟ZCDHJ的个人博客发布,审核需要一段时间. 传送门 考虑题目中获得的糖果并不包含所有的颜色这句话,发现相当于我们可以直接选取某一个颜色强制不能选(这样子一定最优). 然后就可以考虑分开 ...

  3. iOS错误 - too many open files (error = 24)

    碰到这个错误是在用 UIImageView 显示图片的时候.UIImage 用的是 imageNamed 方法.错误原因是打开了太多的文件.应该是太多文件的打开导致了 UIImage 的 cache ...

  4. LOJ121 【离线可过】动态图连通性

    题目链接:戳我 [线段树分治版本代码] 这里面的线段树是时间线段树,每一个节点都要开一个vector,记录当前时间区间中存在的边的标号qwq #include<iostream> #inc ...

  5. 云架构和openstack的思考

    原文链接: http://ifeve.com/cloud-architecture-openstack/ 作者:罗立树 最近在负责公司内部私有云的建设,一直在思考怎么搞云计算,怎么才能够把云架构设计得 ...

  6. ClamAV学习【5】—— cli_scanpe函数浏览

    这近2000行的代码,要是没有Source Insight,都不知道怎么看下去.跟着跟着来到了PE文件查杀的地方,发现前面都中规中矩地进行PE属性检查,中间一段开始扫描每个区块,然后和特征库的size ...

  7. SQLAlchemy和Flask-SQLAlchemy

    一.ORM 与 SQLAlchemy 简介 ORM 全称 Object Relational Mapping, 翻译过来叫对象关系映射.简单的说,ORM 将数据库中的表与面向对象语言中的类建立了一种对 ...

  8. [JS] 四角度旋转特效

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  9. 官宣,PyTorch 1.0 稳定版本现已推出

    简评:快来一起快乐地学习吧. 随着 PyTorch 生态系统和社区继续为开发人员提供有趣的新项目和教育资源,今天(12 月 7日)在 NeurIPS 会议上发布了 PyTorch 1.0 稳定版.研究 ...

  10. Oracle to_char的用法

    The following are number examples for the to_char function. to_char(1210.73, '9999.9') would return ...