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

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. Caffe任务池GPU模型图像识别

    一开始我在网上找demo没有找到,在群里寻求帮助也没有得到结果,索性将网上的易语言模块反编译之后,提取出对应的dll以及代码,然后对照官方的c++代码,写出了下面的c#版本 /*** * @pName ...

  2. Java : java.util.ConcurrentModificationException

    在删除 List 元素的时候,要用 Iterator,不要直接遍历 List,否则会出现 Fatal Exception: java.util.ConcurrentModificationExcept ...

  3. “全栈2019”Java异常第十二章:catch与异常匹配

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  4. JDBC技术(汇聚页)

    JDBC代表Java数据库连接(Java Database Connectivity),它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API, 换句话说:JDBC是用于在Java ...

  5. JAVA 中的 StringBuilder 和 StringBuffer 适用的场景是什么?

    JAVA 中的 StringBuilder 和 StringBuffer 适用的场景是什么? 最简单的回答是,stringbuffer 基本没有适用场景,你应该在所有的情况下选择使用 stringbu ...

  6. BZOJ2961: 共点圆(CDQ分治+凸包)

    题面 传送门 题解 这题解法真是多啊--据说可以圆反演转化为动态插入半平面并判断给定点是否在半平面交中,或者化一下改成给定点判断是否所有点都在某一个半平面内-- 鉴于圆反演我也不会,这里讲一下直接推的 ...

  7. php 递归数据,三维数组转换二维

    public function sortarea($area, $parent_id = 0, $lev = 1){ static $list; foreach($area as $v){ if($v ...

  8. PDF转HTML的方法。

    上个项目客户提出了一个需求,要求把PDF格式的文件转化为HTML格式. 上网查了一下,要么使用软件处理,要么是HTML格式转化为PDF.因为涉及到图文识别问题,所以说仅仅依靠前端不能实现.在网上查了几 ...

  9. P4542 [ZJOI2011]营救皮卡丘

    题目链接 题意分析 我们仔细分析一下 发现题目要求用最多\(k\)条路径实现最小权覆盖 首先由于最小路径覆盖针对的是有向图 但是这是一个无向图 所以我们面向对象编程 我们维护一个数组\(d[i][j] ...

  10. C#-WebForm-LinQ-条件精确查询、高级查询

    前台界面,并在后台绑定数据 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Ca ...