Выбор фильтра
При настройке службы маршрутизации важно выбрать правильные фильтры сообщений и настроить их таким образом, чтобы полученное сообщение всегда определялось одним из них. Если выбранные фильтры допускают избыточные совпадения или неверно настроены, то сообщения будут маршрутизироваться неправильно. Если фильтры слишком строги, то это может привести к тому, что для некоторых сообщений не окажется ни одного допустимого маршрута.
Типы фильтров
При выборе фильтров, используемых службой маршрутизации, важно понимать, каким образом работает каждый из них и какие сведения имеются во входящих сообщениях. Например, если все сообщения получаются одной и той же конечной точкой, то фильтры Address и EndpointName не рекомендуется использовать вместе, так как все сообщения будут определены этими фильтрами.
Действие
Фильтр Action проверяет свойство Action. Если содержимое заголовка Action в сообщении соответствует значению данных фильтра, которое указано в конфигурации фильтра, то этот фильтр возвращает значение true
. В следующем примере определяется, FilterElement
в котором фильтр действий используется для сопоставления сообщений с заголовком действия, содержащим значение http://namespace/contract/operation/
.
<filter name="action1" filterType="Action" filterData="http://namespace/contract/operation/" />
ActionMessageFilter action1 = new ActionMessageFilter(new string[] { "http://namespace/contract/operation" });
Этот фильтр следует использовать при маршрутизации сообщений, которые содержат заголовок Action.
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 ищет совпадение начала адреса с шаблоном, заданным в конфигурации фильтра. В следующем примере определяется, 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
не выполняет непосредственную фильтрацию по значению в сообщении. Он позволяет объединять два других фильтра, создав условие логического умножения, при котором оба фильтра должны соответствовать сообщению, чтобы результат оценки фильтра принял значение 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);
Этот фильтр должен использоваться в тех случаях, когда необходимо логически объединить несколько фильтров. Например, если существует несколько целевых объектов, которые должны получать только определенные сочетания действий и сообщений по определенным адресам, то можно объединить фильтры Action и Address с помощью фильтра AND.
Пользовательское
При выборе типа пользовательского фильтра необходимо указать значение customType, содержащее тип сборки, содержащей реализацию MessageFilter , которая будет использоваться для этого фильтра. Кроме того, filterData должно содержать все значения, которые пользовательскому фильтру могут потребоваться для проверки сообщений. В следующем примере определяется FilterElement
, который использует реализацию класса MessageFilter - CustomAssembly.MyCustomMsgFilter
.
<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
Фильтр EndpointName проверяет имя конечной точки, которая получила сообщение. В следующем примере определяется, FilterElement
который использует фильтр EndpointName для маршрутизации сообщений, полученных в SvcEndpoint.
<filter name="name1" filterType="Endpoint" filterData="SvcEndpoint" />
EndpointNameMessageFilter name1 = new EndpointNameMessageFilter("SvcEndpoint");
Этот фильтр рекомендуется использовать в тех случаях, когда служба маршрутизации обеспечивает доступ к нескольким именованным конечным точкам служб. Например, можно реализовать две конечные точки, используемые службой маршрутизации для получения сообщений. Одна из них предназначена для важных клиентов, которым требуется обработка сообщений в режиме реального времени, а вторая будет обрабатывать сообщения, время обработки которых не критично.
Можно использовать сопоставление по полному адресу для определения конечной точки, которая получила сообщение, однако использование вместо этого конкретного имени конечной точки является более удобным способом, который обычно менее подвержен ошибкам, особенно при настройке службы маршрутизации через файл конфигурации (где имена конечных точек являются обязательными атрибутами).
MatchAll
Фильтр MatchAll выполняет сопоставление всех полученных сообщений. Этот фильтр рекомендуется к использованию в том случае, если необходима маршрутизация абсолютно всех полученных сообщений определенной конечной точке, например службе ведения журнала, которая сохраняет копии всех полученных сообщений. В следующем примере определяется FilterElement
, который использует фильтр MatchAll.
<filter name="matchAll1" filterType="MatchAll" />
MatchAllMessageFilter matchAll1 = new MatchAllMessageFilter();
XPath
Фильтр XPath позволяет указать запрос XPath, который используется для проверки определенного элемента в сообщении. Фильтрация XPath является эффективным способом фильтрации, который позволяет напрямую проверять все адресуемые XML-записи в сообщении. Однако для использования этого фильтра необходимо иметь определенные сведения о структуре получаемых сообщений. В следующем примере определяется, FilterElement
который использует фильтр XPath для проверки сообщения для элемента с именем "элемент" в пространстве имен, на которое ссылается префикс пространства имен ns.
<filter name="xpath1" filterType="XPath" filterData="//ns:element" />
XPathMessageFilter xpath1=new XPathMessageFilter("//ns:element");
Этим фильтром рекомендуется пользоваться в тех случаях, когда точно известно, что получаемое сообщение содержит определенное значение. Например, если размещаются две версии одной службы и известно, что сообщение, которое адресовано более новой версии службы, содержит уникальное значение в пользовательском заголовке, можно создать фильтр, который использует XPath для перехода к этому заголовку и выполняет сравнение значения, которое находится в заголовке, со значением, которое указано в конфигурации фильтра, для определения его соответствия фильтру.
Поскольку запросы XPath часто содержат уникальные пространства имен, которые часто представлены очень длинными или сложными строковыми значениями, фильтр XPath позволяет использовать таблицу пространств имен, в которой для пространств имен можно определить уникальные префиксы. Дополнительные сведения о таблице пространства имен см. в разделе "Фильтры сообщений".
Дополнительные сведения о разработке запросов XPath см. в разделе "Синтаксис XPath".