Åtgärdsformaterare och åtgärdsväljare
Exemplet QueryStringFormatter visar hur utökningspunkter för Windows Communication Foundation (WCF) kan användas för att tillåta meddelandedata i ett annat format än vad WCF förväntar sig. WCF-formaterare förväntar sig som standard att metodparametrar inkluderas under elementet soap:body
. Exemplet visar hur du implementerar en anpassad åtgärdsformaterare som parsar parameterdata från en HTTP GET-frågesträng i stället och anropar metoder som använder dessa data.
Exemplet baseras på Komma igång, som implementerar tjänstkontraktet ICalculator
. Den visar hur meddelanden för att lägga till, subtrahera, multiplicera och dela upp kan ändras för att använda HTTP GET för klient-till-server-begäranden och HTTP POST med POX-meddelanden för server-till-klient-svar.
För att göra det tillhandahåller exemplet följande:
QueryStringFormatter
, som implementerar IClientMessageFormatter och IDispatchMessageFormatter för klienten respektive servern och bearbetar data i frågesträngen.UriOperationSelector
, som implementeras på servern för att utföra åtgärdssändning IDispatchOperationSelector baserat på åtgärdsnamnet i GET-begäran.EnableHttpGetRequestsBehavior
slutpunktsbeteende (och motsvarande konfiguration), vilket lägger till den nödvändiga åtgärdsväljaren i körningen.Visar hur du infogar en ny åtgärdsformaterare i körningen.
I det här exemplet är både klienten och tjänsten konsolprogram (.exe).
Kommentar
Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.
Viktiga begrepp
QueryStringFormatter
– Åtgärdsformaterare är komponenten i WCF som ansvarar för att konvertera ett meddelande till en matris med parameterobjekt och en matris med parameterobjekt till ett meddelande. Detta görs på klienten med hjälp av IClientMessageFormatter gränssnittet och på servern med IDispatchMessageFormatter gränssnittet. Dessa gränssnitt gör det möjligt för användare att hämta begärande- och svarsmeddelandena från Serialize
metoderna och Deserialize
.
I det här exemplet QueryStringFormatter
implementerar båda dessa gränssnitt och implementeras på klienten och servern.
Begäran:
Exemplet använder TypeConverter klassen för att konvertera parameterdata i begärandemeddelandet till och från strängar. Om en TypeConverter inte är tillgänglig för en viss typ genererar exempelformaterare ett undantag.
IClientMessageFormatter.SerializeRequest
I -metoden på klienten skapar formateren en URI med rätt Adress och lägger till åtgärdsnamnet som ett suffix. Det här namnet används för att skicka till lämplig åtgärd på servern. Sedan tar den matrisen med parameterobjekt och serialiserar parameterdata till URI-frågesträngen med hjälp av parameternamn och de värden som konverteras av TypeConverter klassen. Egenskaperna To och Via anges sedan till den här URI:n. MessageProperties nås via egenskapen Properties .IDispatchMessageFormatter.DeserializeRequest
I -metoden på servern hämtarVia
formatatorn URI:n i egenskaperna för inkommande begärandemeddelande. Den parsar namn/värde-paren i URI-frågesträngen i parameternamn och värden och använder parameternamnen och värdena för att fylla i matrisen med parametrar som skickas till metoden. Observera att åtgärdens sändning redan har inträffat, så åtgärdsnamnssuffixet ignoreras i den här metoden.
Svar:
- I det här exemplet används HTTP GET endast för begäran. Formateraren delegerar sändningen av svaret till den ursprungliga formatering som skulle ha använts för att generera ett XML-meddelande. Ett av målen med det här exemplet är att visa hur en sådan delegeringsformaterare kan implementeras.
UriPathSuffixOperationSelector-klass
Gränssnittet IDispatchOperationSelector gör det möjligt för användare att implementera sin egen logik för vilken åtgärd ett visst meddelande ska skickas för.
I det här exemplet UriPathSuffixOperationSelector
måste implementeras på servern för att välja lämplig åtgärd eftersom åtgärdsnamnet ingår i HTTP GET-URI:n i stället för ett åtgärdshuvud i meddelandet. Exemplet är konfigurerat för att endast tillåta skiftlägesokänsliga åtgärdsnamn.
Metoden SelectOperation
tar det inkommande meddelandet och söker upp URI:n Via
i dess meddelandeegenskaper. Den extraherar åtgärdsnamnssuffixet från URI:n, letar upp en intern tabell för att hämta åtgärdsnamnet som meddelandet ska skickas till och returnerar åtgärdsnamnet.
EnableHttpGetRequestsBehavior-klass
Komponenten UriPathSuffixOperationSelector
kan konfigureras programmatiskt eller via ett slutpunktsbeteende. Exemplet implementerar beteendet EnableHttpGetRequestsBehavior
, som anges i tjänstens programkonfigurationsfil.
På servern:
OperationSelector Är inställt på implementeringenIDispatchOperationSelector.
Som standard använder WCF ett exakt matchningsadressfilter. URI:n för det inkommande meddelandet innehåller ett åtgärdsnamnssuffix följt av en frågesträng som innehåller parameterdata, så slutpunktsbeteendet ändrar även adressfiltret till ett prefixmatchningsfilter. Den använder WCFPrefixEndpointAddressMessageFilter för detta ändamål.
Installera åtgärdsformaterare
Åtgärdsbeteenden som anger formaterare är unika. Ett sådant beteende implementeras alltid som standard för varje åtgärd för att skapa nödvändig åtgärdsformaterare. Dessa beteenden ser dock ut som bara ett annat åtgärdsbeteende. de kan inte identifieras av något annat attribut. För att installera ett ersättningsbeteende måste implementeringen söka efter specifika formateringsbeteenden som installeras av WCF-typinläsaren som standard och antingen ersätta den eller lägga till ett kompatibelt beteende som ska köras efter standardbeteendet.
Dessa funktionsformateringsbeteenden kan konfigureras programmatiskt före anrop CommunicationObject.Open eller genom att ange ett åtgärdsbeteende som körs efter standardbeteendet. Det kan dock inte enkelt konfigureras av ett slutpunktsbeteende (och därför genom konfiguration) eftersom beteendemodellen inte tillåter att ett beteende ersätter andra beteenden eller på annat sätt ändrar beskrivningsträdet.
På klienten:
Implementeringen IClientMessageFormatter måste implementeras så att den kan konvertera begäranden till HTTP GET-begäranden och delegera till den ursprungliga formateringen för svar. Detta görs genom att anropa EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
hjälpmetoden.
Detta måste göras innan du anropar 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);
}
På servern:
Gränssnittet IDispatchMessageFormatter måste implementeras så att det kan läsa HTTP GET-begäranden och delegera till den ursprungliga formatören för att skriva svar. Detta görs genom att anropa samma
EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
hjälpmetod som klienten (se föregående kodexempel).Detta måste göras innan Open anropas. I det här exemplet visar vi hur formaterare ändras manuellt innan du anropar Open. Ett annat sätt att uppnå samma sak är att härleda en klass från ServiceHost som gör anropen till
EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
innan du öppnar (se värddokumentation och exempel för exempel).
Användarupplevelse
På servern:
Serverimplementeringen
ICalculator
behöver inte ändras.App.config för tjänsten måste använda en anpassad POX-bindning som anger
messageVersion
-attributet för -elementettextMessageEncoding
tillNone
.<bindings> <customBinding> <binding name="poxBinding"> <textMessageEncoding messageVersion="None" /> <httpTransport /> </binding> </customBinding> </bindings>
App.config för tjänsten måste också ange den anpassade
EnableHttpGetRequestsBehavior
genom att lägga till den i avsnittet beteendetillägg och använda den.<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>
Lägg till åtgärdsformaterare innan du anropar Open.
På klienten:
Klientimplementeringen behöver inte ändras.
App.config för klienten måste använda en anpassad POX-bindning som anger
messageVersion
-attributet för elementettextMessageEncoding
tillNone
. En skillnad från tjänsten är att klienten måste aktivera manuell adressering så att den utgående Till-adressen kan ändras.<bindings> <customBinding> <binding name="poxBinding"> <textMessageEncoding messageVersion="None" /> <httpTransport manualAddressing="True" /> </binding> </customBinding> </bindings>
App.config för klienten måste ange samma anpassade
EnableHttpGetRequestsBehavior
som servern.Lägg till åtgärdsformaterare innan du anropar CreateChannel().
När du kör exemplet visas åtgärdsbegäranden och svar i klientkonsolfönstret. Alla fyra åtgärderna (Add, Subtract, Multiply och Divide) måste lyckas.
Så här konfigurerar du, skapar och kör exemplet
Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.
Skapa lösningen genom att följa anvisningarna i Skapa Windows Communication Foundation-exempel.
Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.