Erweiterte FilterAdvanced Filters

Dieses Beispiel zeigt einen Windows Communication Foundation (WCF)-routing-Dienst.This sample demonstrates a Windows Communication Foundation (WCF) routing service. Der Routingdienst ist eine WCF-Komponente, die integrieren ein inhaltsbasierten Routers in die Anwendung aufnehmen vereinfacht.The routing service is a WCF component that makes it easy to include a content-based router in your application. In diesem Beispiel wird der standardmäßigen WCF--Rechnerbeispiel für die Kommunikation über den Routingdienst angepasst.This sample adapts the standard WCF Calculator sample to communicate using the routing service. In diesem Beispiel wird gezeigt, wie die inhaltsbasierte Routinglogik durch die Verwendung von Nachrichtenfiltern und Nachrichtenfiltertabellen definiert wird.This sample shows how to define content-based routing logic through the use of message filters and message filter tables.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your computer. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\RoutingServices\AdvancedFilters

BeispieldetailsSample Details

In der folgenden Tabelle werden die Nachrichtenfilter angezeigt, die der Nachrichtenfiltertabelle des Routingdiensts hinzugefügt werden.The following table shows the message filters that are added to the message filter table of the routing service.

FilterFilter RegelRule PrioritätPriority
If (hat Header)If (has header) RundenRounding 22
If (angezeigt an Ep2)If (showed up on Ep2) RegulärRegular 11
If (angezeigt mit Address2)If (showed up with Address2) RundenRounding 11
If (RoundRobin1)If (RoundRobin1) RegulärRegular 00
If (RoundRobin2)If (RoundRobin2) RundenRounding 00

Die Nachrichtenfilter und Nachrichtenfiltertabellen können entweder durch Code oder in der Anwendungskonfigurationsdatei erstellt und konfiguriert werden.The message filters and message filter tables can be created and configured either through code or in the application configuration file. Für dieses Beispiel finden Sie die durch Code definierten Nachrichtenfilter und Nachrichtenfiltertabellen in der Datei RoutingService\routing.cs bzw. die in der Anwendungskonfigurationsdatei definierten Nachrichtenfilter und Nachrichtenfiltertabellen in der Datei RoutingService\App.config.For this sample, you can find the message filters and message filter tables defined through code in the RoutingService\routing.cs file, or defined in the application configuration file in the RoutingService\App.config file. In den folgenden Absätzen wird beschrieben, wie die Nachrichtenfilter und Nachrichtenfiltertabellen für dieses Beispiel durch Code erstellt werden.The following paragraphs describe how the message filters and message filter tables are created for this sample through code.

Zuerst sucht ein XPathMessageFilter nach dem benutzerdefinierten Header.First, an XPathMessageFilter looks for the custom header. Beachten Sie, dass WSHttpBinding zu einer Umschlagversion führt, die SOAP 1.2 verwendet, sodass die XPath-Anweisung für die Verwendung des SOAP 1.2-Namespace definiert wird.Note that WSHttpBinding results in an envelope version using SOAP 1.2, so the XPath statement is defined to use the SOAP 1.2 namespace. Der standardmäßige Namespace-Manager für XPathMessageFilter definiert bereits ein Präfix für den SOAP 1.2-Namespace, /s12, das verwendet werden kann.The default namespace manager for XPathMessageFilters already defines a prefix for the SOAP 1.2 namespace, /s12, which can be used. Der standardmäßige Namespace-Manager verfügt jedoch nicht über den benutzerdefinierten Namespace, mit dem der Client den tatsächlichen Headerwert definiert, sodass dieses Präfix definiert werden muss.However, the default namespace manager does not have the custom namespace that the client uses to define the actual header value, so that prefix must be defined. Der Filter ergibt für jede Nachricht, die mit diesem Header angezeigt wird, eine Übereinstimmung.Any message that shows up with this header matches this filter.

XPathMessageContext namespaceManager = new XPathMessageContext();  
namespaceManager.AddNamespace("custom", "http://my.custom.namespace/");  

XPathMessageFilter xpathFilter = new XPathMessageFilter("/s12:Envelope/s12:Header/custom:RoundingCalculator = 1", namespaceManager);  

Der zweite Filter ist ein EndpointNameMessageFilter, der für jede Nachricht eine Übereinstimmung ergibt, die am calculatorEndpoint empfangen wurde.The second filter is an EndpointNameMessageFilter, which matches any message that was received on the calculatorEndpoint. Der Endpunktname wird definiert, wenn ein Dienstendpunktobjekt erstellt wird.The endpoint name is defined when a service endpoint object is created.

EndpointNameMessageFilter endpointNameFilter = new EndpointNameMessageFilter("calculatorEndpoint");  

Der dritte Filter ist ein PrefixEndpointAddressMessageFilter.The third filter is a PrefixEndpointAddressMessageFilter. Dieser Filter ergibt für jede Nachricht eine Übereinstimmung, die an einem Endpunkt mit einer Adresse angezeigt wurde, die mit dem angegebenen Adresspräfix (oder dem Anfang) übereinstimmt.This matches any message that showed up on an endpoint with an address that matches the address prefix (or the front portion) provided. In diesem Beispiel wird das Adresspräfix als definiert "http://localhost/routingservice/router/rounding/".In this example the address prefix is defined as "http://localhost/routingservice/router/rounding/". Dies bedeutet, dass alle eingehenden Nachrichten, die an adressiert sind "http://localhost/routingservice/router/rounding/*", die von diesem Filter abgeglichen werden.This means that any incoming messages that are addressed to "http://localhost/routingservice/router/rounding/*" are matched by this filter. In diesem Fall ist es Nachrichten, die auf den rundungsrechnerendpunkt angezeigt werden, werden die hat der Adresse des "http://localhost/routingservice/router/rounding/calculator".In this case, it is messages that show up on the Rounding Calculator endpoint, which has the address of "http://localhost/routingservice/router/rounding/calculator".

PrefixEndpointAddressMessageFilter prefixAddressFilter = new PrefixEndpointAddressMessageFilter(new EndpointAddress("http://localhost/routingservice/router/rounding/"));  

Die letzten beiden Nachrichtenfilter sind benutzerdefinierte MessageFilter.The last two message filters are custom MessageFilters. In diesem Beispiel wird ein "RoundRobin"-Nachrichtenfilter verwendet.In this example, a "RoundRobin" message filter is used. Dieser Nachrichtenfilter wird in der bereitgestellten Datei RoutingService\RoundRobinMessageFilter.cs erstellt.This message filter is created in the provided RoutingService\RoundRobinMessageFilter.cs file. Wenn diese Filter für dieselbe Gruppe festgelegt werden, melden sie abwechselnd, dass sie mit der Nachricht übereinstimmen und dass sie nicht mit der Nachricht übereinstimmen, sodass zu jedem gegebenen Zeitpunkt nur ein Filter true zurückgibt.These filters, when set to the same group, alternate between reporting that they match the message and that they do not, such that only one of them responds true at a time.

RoundRobinMessageFilter roundRobinFilter1 = new RoundRobinMessageFilter("group1");  

RoundRobinMessageFilter roundRobinFilter2 = new RoundRobinMessageFilter("group1");  

Als Nächstes werden diese Nachrichten zu einer MessageFilterTable<TFilterData> hinzugefügt.Next, all of those messages are added to a MessageFilterTable<TFilterData>. Dadurch werden Prioritäten festgelegt, die die Reihenfolge beeinflussen, in der die Filter in der Nachrichtenfiltertabelle ausgeführt werden.In doing so, priorities are specified to influence the order in which the message filter table executes the filters. Je höher die Priorität, desto früher wird der Filter ausgeführt; je niedriger die Priorität, desto später wird ein Filter ausgeführt.The higher the priority, the sooner the filter is executed; the lower the priority, the later a filter is executed. So wird ein Filter mit Priorität 2 vor einem Filter mit Priorität 1 ausgeführt.Thus a filter at priority 2 runs before a filter at priority 1. Wenn keine Priorität angegeben wird, wird die Standardprioritätsstufe 0 verwendet.The default priority level if none is specified is 0. In einer Nachrichtenfiltertabelle werden alle Filter einer bestimmten Prioritätsstufe ausgeführt, bevor zur nächst niedrigeren Prioritätsstufe übergegangen wird.A message filter table executes all of the filters at a given priority level before moving to the next lowest priority level. Wenn eine Übereinstimmung gefunden wird, fährt die Nachrichtenfiltertabelle nicht auf der nächst niedrigeren Prioritätsstufe mit der Suche nach Übereinstimmungen fort.If a match is found at a particular priority, then the message filter table does not continue trying to find matches at the next lower priority.

Hinweis

In diesem Beispiel wird zwar die Verwendung von Nachrichtenfilterprioritäten gezeigt, im Allgemeinen empfiehlt es sich jedoch, die Filter so zu entwerfen und zu konfigurieren, dass sie keine Prioritäten benötigen, um ordnungsgemäß zu funktionieren, weil dadurch eine höhere Leistung und Anwendbarkeit erzielt wird.While this example shows how to use message filter priorities, in general it is more performant and better design to design and configure your filters such that they do not require prioritization to function correctly.

Der erste hinzuzufügende Filter ist der XPath-Filter, und seine Priorität ist auf 2 festgelegt.The first filter to be added is the XPath filter and its priority is set to 2. Dies ist der erste Nachrichtenfilter, der ausgeführt wird.This is the first message filter that executes. Wenn er den benutzerdefinierten Header findet, wird die Nachricht unabhängig von den möglichen Ergebnissen der anderen Filter an den Rundungsrechnerendpunkt weitergeleitet.If it finds the custom header, regardless of what the results of the other filters would be, the message is routed to the Rounding Calculator endpoint.

Zwei Filter werden mit Priorität 1 hinzugefügt.At priority 1, two filters are added. Diese werden wiederum nur ausgeführt, wenn der XPath-Filter mit Priorität 2 für die Nachricht keine Übereinstimmung ergibt.Again, these only run if the XPath filter at priority 2 does not match the message. Diese beiden Filter zeigen zwei verschiedene Möglichkeiten, um zu bestimmen, wo die Nachricht adressiert wurde, als sie angezeigt wurde.These two filters show two different ways to determine where the message was addressed when it showed up. Da die beiden Filter effektiv überprüfen, ob die Nachricht an einem der beiden Endpunkte eingegangen ist, können sie mit derselben Prioritätsstufe ausgeführt werden, da sie nicht beide gleichzeitig true zurückgegeben.Because the two filters effectively check to see whether the message arrived at one of the two endpoints, they can be run at the same priority level because they do not both return true at the same time.

Führen Sie schließlich die RoundRobin-Nachrichtenfilter auf der Prioritätsstufe 0 (der niedrigsten Priorität) aus.Finally, at Priority 0 (the lowest priority) run the RoundRobin message filters. Da die Filter mit demselben Gruppennamen konfiguriert sind, ergibt immer nur einer eine Übereinstimmung.Because the filters are configured with the same group name, only one of them matches at a time. Da alle Nachrichten mit dem benutzerdefinierten Header und alle Nachrichten, die an die bestimmten virtualisierten Endpunkte adressiert sind, weitergeleitet wurden, werden nur die Nachrichten von RoundRobin-Nachrichtenfiltern verarbeitet, die an den Standardrouterendpunkt ohne den benutzerdefinierten Header adressiert waren.Because all messages with the custom header have been routed and all those addressed to the specific virtualized endpoints, messages handled by the RoundRobin message filters are only messages that were addressed to the default router endpoint without the custom header. Da für diese Nachrichten bei jedem Aufruf ein Wechsel stattfindet, wird die Hälfte der Vorgänge an den regulären Rechnerendpunkt und die andere Hälfte an den Rundungsrechnerendpunkt geleitet.Because these messages switch on a message for each call, half of the operations go to the Regular Calculator endpoint and the other half go to the Rounding Calculator endpoint.

So verwenden Sie dieses BeispielTo use this sample

  1. Öffnen Sie AdvancedFilters.sln in Visual Studio 2012Visual Studio 2012.Using Visual Studio 2012Visual Studio 2012, open AdvancedFilters.sln.

  2. So öffnen Projektmappen-Explorerwählen Projektmappen-Explorer aus der Ansicht Menü.To open Solution Explorer, select Solution Explorer from the View menu.

  3. Drücken Sie F5 oder STRG + UMSCHALT + B in Visual Studio aus.Press F5 or CTRL+SHIFT+B in Visual Studio.

    1. Möchten Sie die notwendigen Projekte automatisch gestartet, wenn Sie F5 drücken, Maustaste auf die Projektmappe, und wählen Sie Eigenschaften.If you would like to auto-launch the necessary projects when you press F5, right-click the solution and select Properties. Wählen Sie die Startprojekt Knoten unter allgemeine Eigenschaften im linken Bereich.Select the Startup Project node under Common Properties in the left pane. Wählen Sie die mehrere Startprojekte Optionsfeld aus, und legen Sie alle Projekte haben die starten Aktion.Select the Multiple Startup Projects radio button and set all of the projects to have the Start action.

    2. Wenn Sie das Projekt mit STRG+UMSCHALT+B erstellen, müssen Sie die folgenden Anwendungen starten:If you build the project with CTRL+SHIFT+B, you must start the following applications:

      1. Rechnerclient (./CalculatorClient/bin/client.exe)Calculator Client (./CalculatorClient/bin/client.exe)

      2. Rechnerdienst (./CalculatorService/bin/service.exe)Calculator Service (./CalculatorService/bin/service.exe)

      3. Routingrechnerdienst (./RoundingCalcService/bin/service.exe)Routing Calculator Service (./RoundingCalcService/bin/service.exe)

      4. Routingdienst (./RoutingService/bin/RoutingService.exe)RoutingService (./RoutingService/bin/RoutingService.exe)

  4. Drücken Sie im Konsolenfenster des Rechnerclients die EINGABETASTE, um den Client zu starten.In the console window of the Calculator client, press ENTER to start the client. Der Client gibt eine Liste mit Zielendpunkten zur Auswahl zurück.The client returns a list of destination endpoints to choose from.

  5. Wählen Sie einen Zielendpunkt aus, indem Sie den entsprechenden Buchstaben eingeben und die EINGABETASTE drücken.Choose a destination endpoint by typing its corresponding letter and press ENTER.

  6. Als Nächstes fordert Sie der Client auf, einzugeben, ob ein benutzerdefinierter Header hinzugefügt werden soll.Next, the client asks you if you want to add a custom header. Drücken Sie Y für Ja oder N für Nein, und drücken Sie dann die EINGABETASTE.Press Y for Yes or N for No, then press ENTER.

  7. Abhängig von der getroffenen Auswahl werden unterschiedliche Ausgaben angezeigt.Depending on the selections you made, you should see different outputs.

    1. Die folgende Ausgabe wird zurückgegeben, wenn Sie einen benutzerdefinierten Header zu den Nachrichten hinzugefügt haben.The following is the output returned if you added a custom header to the messages.

      Add(100,15.99) = 116  
      Subtract(145,76.54) = 68.5  
      Multiply(9,81.25) = 731.3  
      Divide(22,7) = 3.1  
      
    2. Die folgende Ausgabe wird zurückgegeben, wenn Sie den Rundungsrechnerendpunkt ohne benutzerdefinierten Header ausgewählt haben.The following is the output returned if you chose the Rounding Calculator endpoint without a custom header.

      Add(100,15.99) = 116  
      Subtract(145,76.54) = 68.5  
      Multiply(9,81.25) = 731.3  
      Divide(22,7) = 3.1  
      
    3. Die folgende Ausgabe wird zurückgegeben, wenn Sie den regulären Rechnerendpunkt ohne benutzerdefinierten Header ausgewählt haben.The following is the output returned if you chose the Regular Calculator endpoint without a custom header.

      Add(100,15.99) = 115.99  
      Subtract(145,76.54) = 68. 46  
      Multiply(9,81.25) = 731.25  
      Divide(22,7) = 3.14285714285714  
      
    4. Die folgende Ausgabe wird zurückgegeben, wenn Sie den Standardrouterendpunkt ohne benutzerdefinierten Header ausgewählt haben.The following is the output returned if you chose the Default Router endpoint without a custom header.

      Add(100,15.99) = 116  
      Subtract(145,76.54) = 68.46  
      Multiply(9,81.25) = 731.3  
      Divide(22,7) = 3.14285714285714  
      
  8. Vom Rechnerdienst und Rundungsrechnerdienst wird außerdem ein Protokoll der Vorgänge gedruckt, die in den jeweiligen Konsolenfenstern aufgerufen werden.The Calculator Service and the Rounding Calculator Service also prints out a log of the operations invoked to their respective console windows.

  9. Geben Sie im Konsolenfenster Clients quit , und drücken Sie EINGABETASTE, um zu beenden.In the client console window, type quit and press ENTER to exit.

  10. Drücken Sie die EINGABETASTE in den Dienstkonsolenfenstern, um die Dienste zu beenden.Press ENTER in the services console windows to terminate the services.

Konfigurierbar über Code oder App.configConfigurable Via Code or App.config

Das Beispiel wird so konfiguriert geliefert, dass die Datei App.config das Verhalten des Routers definiert.The sample ships configured to use an App.config file to define the router’s behavior. Sie können außerdem den Namen der Datei RoutingService\App.config ändern, damit er nicht erkannt wird, und die Auskommentierung des Methodenaufrufs von ConfigureRouterViaCode() in RoutingService\routing.cs aufheben.You can also change the name of the RoutingService\App.config file to something else so that it is not recognized and uncomment the method call to ConfigureRouterViaCode() in RoutingService\routing.cs. Beide Methoden führen zum gleichen Routerverhalten.Either method results in the same behavior from the router.

SzenarioScenario

In diesem Beispiel wird der Router als inhaltsbasierter Router dargestellt, der ermöglicht, dass mehrere Typen oder Implementierungen von Diensten über einen Endpunkt verfügbar gemacht werden.This sample demonstrates the router acting as a content-based router allowing multiple types or implementation of services to be exposed through one endpoint.

Reales SzenarioReal World Scenario

Contoso möchte sämtliche Dienste virtualisieren, um nur einen Endpunkt öffentlich verfügbar zu machen, über den Zugriff auf mehrere verschiedene Dienste gewährt wird.Contoso wants to virtualize all of their services to expose only one endpoint publicly through which they offer access to multiple different types of services. In diesem Fall werden die inhaltsbasierten Routingfunktionen des Routingdiensts verwendet, um zu bestimmen, wohin die eingehenden Anforderungen gesendet werden sollen.In this case they utilize the routing service’s content-based routing capabilities to determine where the incoming requests should be sent.

Siehe auchSee Also

AppFabric-Hosting und PersistenzbeispieleAppFabric Hosting and Persistence Samples