Delen via


Operatieformatter en operatieselector

Het querystringFormatter-voorbeeld laat zien hoe WCF-uitbreidbaarheidspunten (Windows Communication Foundation) kunnen worden gebruikt om berichtgegevens in een andere indeling toe te staan dan wat WCF verwacht. WCF-formatters verwachten standaard dat methodeparameters worden opgenomen in het soap:body element. In het voorbeeld ziet u hoe u een aangepaste bewerkingsindeling implementeert waarmee parametergegevens uit een HTTP GET-queryreeks worden geparseerd en methoden worden aangeroepen met behulp van die gegevens.

Het voorbeeld is gebaseerd op de Getting Started, waarmee het ICalculator service contract wordt geïmplementeerd. Het laat zien hoe berichten optellen, aftrekken, vermenigvuldigen en delen kunnen worden gewijzigd om HTTP GET te gebruiken voor client-naar-server-aanvragen en HTTP POST met POX-berichten voor server-naar-client-antwoorden.

Hiervoor biedt het voorbeeld het volgende:

  • QueryStringFormatter, die respectievelijk IClientMessageFormatter voor de client en IDispatchMessageFormatter voor de server implementeert en de gegevens in de queryreeks verwerkt.

  • UriOperationSelector, die IDispatchOperationSelector implementeert op de server om bewerkingszending uit te voeren op basis van de naam van de bewerking in de GET-aanvraag.

  • EnableHttpGetRequestsBehavior eindpuntgedrag (en bijbehorende configuratie), waarmee de benodigde bewerkingskiezer wordt toegevoegd aan de runtime.

  • Laat zien hoe u een nieuwe bewerkingsindeling invoegt in de runtime.

  • In dit voorbeeld zijn zowel de client als de service consoletoepassingen (.exe).

Opmerking

De installatieprocedure en build-instructies voor dit voorbeeld bevinden zich aan het einde van dit onderwerp.

Belangrijkste concepten

QueryStringFormatter - De operationformatter is het onderdeel in WCF dat verantwoordelijk is voor het converteren van een bericht naar een array van parameterobjecten en een array van parameterobjecten in een bericht. Dit gebeurt op de client met behulp van de IClientMessageFormatter interface en op de server met de IDispatchMessageFormatter interface. Met deze interfaces kunnen gebruikers de aanvraag- en antwoordberichten van de Serialize en Deserialize methoden ophalen.

In dit voorbeeld implementeert QueryStringFormatter beide interfaces en wordt het zowel op de client als op de server gebruikt.

Aanvraag:

  • In het voorbeeld wordt de TypeConverter klasse gebruikt om parametergegevens in het aanvraagbericht naar en van tekenreeksen te converteren. Als een TypeConverter niet beschikbaar is voor een specifiek type, genereert de voorbeeldopmaaker een uitzondering.

  • In de IClientMessageFormatter.SerializeRequest methode op de client maakt de formatter een URI met het juiste To-adres en voegt de naam van de bewerking toe als achtervoegsel. Deze naam wordt gebruikt om naar de juiste bewerking op de server door te sturen. Vervolgens wordt de matrix van parameterobjecten gebruikt en worden de parametergegevens geserialiseerd naar de URI-querytekenreeks met behulp van parameternamen en de waarden die door de TypeConverter klasse worden geconverteerd. De To en Via eigenschappen worden vervolgens ingesteld op deze URI. MessageProperties wordt geopend via de Properties eigenschap.

  • In de IDispatchMessageFormatter.DeserializeRequest methode op de server haalt de formatter de Via URI op in de eigenschappen van het binnenkomende aanvraagbericht. Hiermee worden de naam-waardeparen in de URI-queryreeks geparseerd in parameternamen en -waarden en worden de parameternamen en -waarden gebruikt om de matrix met parameters te vullen die zijn doorgegeven aan de methode. Houd er rekening mee dat de uitvoering van de bewerking al heeft plaatsgevonden, dus het achtervoegsel van de bewerkingsnaam wordt in deze methode genegeerd.

Respons:

  • In dit voorbeeld wordt HTTP GET alleen gebruikt voor de aanvraag. De formatter delegeert het verzenden van het antwoord naar de oorspronkelijke formatter die zou zijn gebruikt om een XML-bericht te genereren. Een van de doelstellingen van dit voorbeeld is om te laten zien hoe een dergelijke delegering formatter kan worden geïmplementeerd.

Klasse UriPathSuffixOperationSelector

Met de IDispatchOperationSelector interface kunnen gebruikers hun eigen logica implementeren waarvoor een bepaald bericht moet worden verzonden.

In dit voorbeeld UriPathSuffixOperationSelector moet op de server worden geïmplementeerd om de juiste bewerking te selecteren, omdat de naam van de bewerking is opgenomen in de HTTP GET-URI in plaats van een actieheader in het bericht. Het voorbeeld is zo ingesteld dat alleen namen van niet-hoofdlettergevoelige operaties zijn toegestaan.

De SelectOperation methode gebruikt het binnenkomende bericht en zoekt de URI in de Via berichteigenschappen op. Het haalt het achtervoegsel van de bewerkingsnaam op uit de URI, zoekt een interne tabel op om de naam van de bewerking op te halen waarnaar het bericht moet worden verzonden en retourneert die bewerkingsnaam.

Klasse "EnableHttpGetRequestsBehavior"

Het UriPathSuffixOperationSelector onderdeel kan programmatisch of via een eindpuntgedrag worden ingesteld. Het voorbeeld implementeert het gedrag, dat is opgegeven in het EnableHttpGetRequestsBehavior toepassingsconfiguratiebestand van de service.

Op de server:

De OperationSelector is ingesteld op de IDispatchOperationSelector implementatie.

WCF maakt standaard gebruik van een exact-match-adresfilter. De URI van het binnenkomende bericht bevat een achtervoegsel van de bewerkingsnaam, gevolgd door een querystring die parametergegevens bevat, zodat het eindpuntgedrag ook het adresfilter wijzigt in een voorvoegselovereenkomstfilter. Hiervoor wordt het WCFPrefixEndpointAddressMessageFilter gebruikt.

Installatie van bewerkingsformatters

Operationeel gedrag waarmee formatters worden opgegeven, is uniek. Een dergelijke functionaliteit wordt standaard altijd geïmplementeerd voor elke bewerking om de benodigde operationele formatter te maken. Dit gedrag ziet er echter uit als gewoon een ander bewerkingsgedrag; ze zijn niet identificeerbaar door een ander kenmerk. Als u een vervangingsgedrag wilt installeren, moet de implementatie zoeken naar specifiek formattergedrag dat standaard door het WCF-typelaadprogramma is geïnstalleerd en deze vervangen of een compatibel gedrag toevoegen om na het standaardgedrag uit te voeren.

Deze operation formatteringsgedragingen kunnen programmatisch worden ingesteld voordat CommunicationObject.Open wordt aangeroepen, of door een bewerkingsgedrag op te geven dat na de standaardgedrag wordt uitgevoerd. Het kan echter niet eenvoudig worden ingesteld door een eindpuntgedrag (en daarom door configuratie), omdat het gedragmodel geen gedrag toestaat om ander gedrag te vervangen of anderszins de beschrijvingsstructuur te wijzigen.

Op de client:

De IClientMessageFormatter implementatie moet worden geïmplementeerd, zodat deze de aanvragen kan converteren naar HTTP GET-aanvragen en delegeren naar de oorspronkelijke formatter voor antwoorden. Dit wordt gedaan door de EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior helpermethode aan te roepen.

Dit moet worden gedaan voordat u belt CreateChannel.

void ReplaceFormatterBehavior(OperationDescription operationDescription, EndpointAddress address)
{
    // Remove the DataContract behavior if it is present.
    IOperationBehavior formatterBehavior = operationDescription.Behaviors.Remove<DataContractSerializerOperationBehavior>();
    if (formatterBehavior == null)
    {
        // Remove the XmlSerializer behavior if it is present.
        formatterBehavior = operationDescription.Behaviors.Remove<XmlSerializerOperationBehavior>();
        ...
    }

    // Remember what the innerFormatterBehavior was.
    DelegatingFormatterBehavior delegatingFormatterBehavior = new DelegatingFormatterBehavior(address);
    delegatingFormatterBehavior.InnerFormatterBehavior = formatterBehavior;
   operationDescription.Behaviors.Add(delegatingFormatterBehavior);
}

Op de server:

  • De IDispatchMessageFormatter interface moet worden geïmplementeerd zodat deze HTTP GET-aanvragen kan lezen en kan delegeren aan de oorspronkelijke formatter voor het schrijven van antwoorden. Dit wordt gedaan door dezelfde EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior helpermethode aan te roepen als de client (zie het vorige codevoorbeeld).

  • Dit moet gedaan worden voordat Open wordt aangeroepen. In dit voorbeeld laten we zien hoe de formatter handmatig wordt gewijzigd voordat u aanroept Open. Een andere manier om hetzelfde te bereiken is door een klasse af te leiden van ServiceHost die de aanroepen naar EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior doet voordat u opent (zie de hostingdocumentatie en voorbeelden).

Gebruikerservaring

Op de server:

  • De server-implementatie ICalculator hoeft niet te worden gewijzigd.

  • De App.config voor de service moet een aangepaste POX-binding gebruiken waarmee het messageVersion kenmerk van het textMessageEncoding element wordt ingesteld op None.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    
  • De App.config voor de service moet bovendien de aangepaste EnableHttpGetRequestsBehavior specificeren door deze toe te voegen aan de sectie gedragsextensies en deze te gebruiken.

    <behaviors>
      <endpointBehaviors>
        <behavior name="enableHttpGetRequestsBehavior">
          <enableHttpGetRequests />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    
    <extensions>
      <behaviorExtensions>
        <!-- Enabling HTTP GET requests: Behavior Extension -->
        <add
          name="enableHttpGetRequests"           type="Microsoft.ServiceModel.Samples.EnableHttpGetRequestsBehaviorElement, QueryStringFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>
    
  • Voeg bewerkingsindelingen toe voordat u het Open aanroept.

Op de client:

  • De client-implementatie hoeft niet te worden gewijzigd.

  • De App.config voor de client moet een aangepaste POX-binding gebruiken waarmee het messageVersion kenmerk van het textMessageEncoding element Nonewordt ingesteld op . Een verschil met de service is dat de client handmatige adressering moet inschakelen, zodat het uitgaande adres kan worden gewijzigd.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport manualAddressing="True" />
        </binding>
      </customBinding>
    </bindings>
    
  • De App.config voor de cliënt moet hetzelfde aangepaste EnableHttpGetRequestsBehavior specificeren als de server.

  • Voeg bewerkingsindelingen toe voordat u het CreateChannel() aanroept.

Wanneer u het voorbeeld uitvoert, worden de bewerkingsaanvragen en -antwoorden weergegeven in het clientconsolevenster. Alle vier de bewerkingen (Optellen, Aftrekken, Vermenigvuldigen en Delen) moeten slagen.

Het voorbeeld instellen, compileren en uitvoeren
  1. Zorg ervoor dat u de One-Time Setup Procedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.

  2. Volg de instructies in Het bouwen van de Windows Communication Foundation-voorbeelden om de oplossing te bouwen.

  3. Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Windows Communication Foundation-voorbeelden uitvoeren.