配置路由服务时,请务必选择正确的消息筛选器并对其进行配置,以便根据收到的消息进行完全匹配。 如果选择的筛选器在其匹配中过于广泛或配置错误,则消息路由不正确。 如果筛选器限制过大,则可能没有可用于某些邮件的有效路由。
筛选器类型
选择路由服务使用的筛选器时,请务必了解每个筛选器的工作原理以及作为传入消息的一部分提供的信息。 例如,如果通过同一终结点接收所有消息,则 Address 和 EndpointName 筛选器无效,因为所有消息都与这些筛选器匹配。
行动
操作筛选器检查 Action 属性。 如果消息中的 Action 标头的内容与筛选器配置中指定的筛选器数据值匹配,则此筛选器返回 true。 以下示例定义了一个 FilterElement,它使用 Action 筛选器来匹配消息,其动作标头包含 http://namespace/contract/operation/ 值。
<filter name="action1" filterType="Action" filterData="http://namespace/contract/operation/" />
ActionMessageFilter action1 = new ActionMessageFilter(new string[] { "http://namespace/contract/operation" });
在路由包含唯一操作标头的消息时,应使用此过滤器。
终端地址
EndpointAddress 筛选器会检查消息接收所使用的 EndpointAddress。 如果消息到达的地址与筛选器配置中指定的筛选器地址完全匹配,则此筛选器返回 true。 以下示例定义一个 FilterElement,它使用地址筛选器匹配地址为“http://<hostname>/vdir/s.svc/b”的任何消息。
<filter name="address1" filterType="EndpointAddress" filterData="http://host/vdir/s.svc/b" />
EndpointAddressMessageFilter address1 = new EndpointAddressMessageFilter(new EndpointAddress("http://host/vdir/s.svc/b"), false);
注释
请务必注意,地址的主机名部分可能因客户端使用完全限定的域名、NetBIOS 名称、IP 地址或其他名称而异。 由于不同的值可以引用同一主机,因此此比较的默认行为是在执行匹配时不使用地址的主机名部分。
可以对此行为进行修改,以便在以编程方式配置路由服务时允许比较操作计算主机名。
将传入消息寻址到唯一地址时,应使用此筛选器。
EndpointAddressPrefix
EndpointAddressPrefix 筛选器类似于 EndpointAddress 筛选器。 EndpointAddressPrefix 筛选器检查接收消息的 EndpointAddress。 但是,EndpointAddressPrefix 筛选器通过匹配以筛选器配置指定的值开头的地址,发挥通配符的作用。 以下示例定义一个 FilterElement,使用 EndpointAddressPrefix 筛选器以匹配发送到 http://<hostname>/vdir* 的任何消息。
<filter name="prefix1" filterType="EndpointAddressPrefix" filterData="http://host/vdir" />
PrefixEndpointAddressMessageFilter prefix1 = new PrefixEndpointAddressMessageFilter(new EndpointAddress("http://host/vdir/s.svc/b"), false);
注释
请务必注意,地址的主机名部分可能因客户端使用完全限定的域名、NetBIOS 名称、IP 地址或其他名称而异。 由于不同的值可以引用同一主机,因此此比较的默认行为是在执行匹配时不使用地址的主机名部分。
路由共享公用地址前缀的传入消息时,应使用此筛选器。
和
AND 筛选器不会直接筛选消息中的某个值,而是允许您合并另外两个筛选器,以创建一个条件,其中两个 AND 筛选器必须同时匹配消息,之后 AND 筛选器才会进行评估为 true。 这样,就可以创建仅当所有子筛选器匹配时匹配的复杂筛选器。 以下示例定义地址过滤器和动作过滤器,然后定义一个 AND 过滤器,该过滤器对消息进行评估,以同时考量地址和动作过滤器。 如果地址和操作筛选器都匹配,则筛选器 AND 返回 true。
<filter name="address1" filterType="AddressPrefix" filterData="http://host/vdir"/>
<filter name="action1" filterType="Action" filterData="http://namespace/contract/operation/"/>
<filter name="and1" filterType="And" filter1="address1" filter2="action1" />
EndpointAddressMessageFilter address1 = new EndpointAddressMessageFilter(new EndpointAddress("http://host/vdir/s.svc/b"), false);
ActionMessageFilter action1 = new ActionMessageFilter(new string[] { "http://namespace/contract/operation" });
StrictAndMessageFilter and1=new StrictAndMessageFilter(address1, action1);
当必须合并来自多个筛选器的逻辑以确定何时应进行匹配时,应使用此筛选器。 例如,如果您有多个目标,而这些目标只能接收发送到特定地址的操作和消息的某些组合,则可以使用 AND 筛选器组合必要的 Action 筛选器和 Address 筛选器。
习惯
选择自定义筛选器类型时,必须提供一个 customType 值,该值包含包含要用于此筛选器的 MessageFilter 实现的程序集的类型。 此外,filterData 必须包含自定义筛选器在其消息评估中可能需要的任何值。 下面的示例定义一个 FilterElement,它使用 CustomAssembly.MyCustomMsgFilter MessageFilter 实现。
<filter name="custom1" filterType="Custom" customType="CustomAssembly.MyCustomMsgFilter, CustomAssembly" filterData="Custom Data" />
MyCustomMsgFilter custom1=new MyCustomMsgFilter("Custom Data");
如果需要对 .NET Framework 4.6.1 提供的筛选器未涵盖的消息执行自定义匹配逻辑,则必须创建自定义筛选器,该筛选器是 MessageFilter 类的实现。 例如,可以创建自定义筛选器,该筛选器将传入消息中的字段与给定为筛选器的已知值列表进行比较,或者该筛选器对特定消息元素进行哈希处理,然后检查该值以确定筛选器是否应返回 true 或 false。
端点名称
EndpointName 筛选器检查接收消息的终结点的名称。 以下示例定义了一个名为“SvcEndpoint”的 FilterElement,使用 EndpointName 筛选器来路由收到的消息。
<filter name="name1" filterType="Endpoint" filterData="SvcEndpoint" />
EndpointNameMessageFilter name1 = new EndpointNameMessageFilter("SvcEndpoint");
当路由服务公开多个命名服务终结点时,此筛选器非常有用。 例如,可以公开路由服务用于接收消息的两个终结点;一个由需要实时处理其消息的优先级客户使用,而另一个终结点则接收不区分时间的消息。
虽然通常可以使用完整地址匹配来确定收到消息的终结点,但改用定义的终结点名称是一种方便的快捷方式,通常不太容易出错,尤其是在使用配置文件(其中终结点名称是必需属性)配置路由服务时。
MatchAll
MatchAll 筛选器匹配任何收到的消息。 如果必须始终将所有收到的消息路由到特定终结点,例如存储所有已接收消息副本的日志记录服务,则此方法非常有用。 以下示例定义了一个使用 MatchAll 筛选器的 FilterElement。
<filter name="matchAll1" filterType="MatchAll" />
MatchAllMessageFilter matchAll1 = new MatchAllMessageFilter();
XPath
使用 XPath 筛选器可以指定用于检查消息中特定元素的 XPath 查询。 XPath 筛选是一个功能强大的筛选选项,可用于直接检查消息中的任何 XML 可寻址条目;但是,它要求你对接收的消息的结构有特定了解。 以下示例定义了一个 FilterElement,使用 XPath 筛选器对消息进行检查,以找出命名空间前缀“ns”引用的命名空间中的名为“element”的元素。
<filter name="xpath1" filterType="XPath" filterData="//ns:element" />
XPathMessageFilter xpath1=new XPathMessageFilter("//ns:element");
如果知道收到的消息包含特定值,则此筛选器非常有用。 例如,如果要托管同一服务的两个版本,并且知道发送到较新版本的服务的消息在自定义标头中包含唯一值,则可以创建一个筛选器,该筛选器使用 XPath 导航到此标头,并将标头中存在的值与筛选器配置中的另一个给定值进行比较,以确定筛选器是否匹配。
由于 XPath 查询通常包含唯一的命名空间(通常是冗长或复杂的字符串值),因此 XPath 筛选器允许你使用命名空间表来定义命名空间的唯一前缀。 有关命名空间表的详细信息,请参阅 消息筛选器。
有关设计 XPath 查询的详细信息,请参阅 XPath 语法。