Share via


Bewerkingsopmaak en bewerkingskiezer

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 aan de slag, waarmee het ICalculator servicecontract 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, waarmee respectievelijk de client en server worden geïmplementeerd IClientMessageFormatter en IDispatchMessageFormatter verwerkt en worden de gegevens in de querytekenreeks 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).

Notitie

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

Belangrijkste concepten

QueryStringFormatter - De bewerkingsindeling is het onderdeel in WCF dat verantwoordelijk is voor het converteren van een bericht naar een matrix van parameterobjecten en een matrix 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 QueryStringFormatter worden beide interfaces geïmplementeerd en geïmplementeerd op de client en server.

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 te verzenden. 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 het verzenden van bewerkingen al is opgetreden, dus het achtervoegsel van de bewerkingsnaam wordt genegeerd in deze methode.

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 hoofdlettergevoelige bewerkingen 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 op het binnenkomende bericht bevat een achtervoegsel van de bewerkingsnaam, gevolgd door een querytekenreeks die parametergegevens bevat, zodat het eindpuntgedrag ook het adresfilter wijzigt in een filter voorvoegselovereenkomst. Hiervoor wordt het WCFPrefixEndpointAddressMessageFilter gebruikt.

Bewerkingsindelingen installeren

Bewerkingsgedrag waarmee formatters worden opgegeven, zijn uniek. Een dergelijk gedrag wordt altijd standaard geïmplementeerd voor elke bewerking om de benodigde bewerkingsindeling 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 bewerkingsindelingen kunnen programmatisch worden ingesteld voordat ze worden aangeroepen CommunicationObject.Open of door een bewerkingsgedrag op te geven dat na de standaardbewerking 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 worden gedaan voordat Open deze 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 waaruit de aanroepen worden gedaan EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior voordat u begint (zie de hostingdocumentatie en voorbeelden voor 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 Nonewordt ingesteld op.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    
  • De App.config voor de service moet ook de aangepaste EnableHttpGetRequestsBehavior opgeven 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 aanroept Open.

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 wordt Noneingesteld 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 client moet dezelfde aangepaste EnableHttpGetRequestsBehavior als de server opgeven.

  • Voeg bewerkingsindelingen toe voordat u aanroept CreateChannel().

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 eenmalige installatieprocedure 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 Het uitvoeren van de Windows Communication Foundation-voorbeelden.