Element formatujący operacji i selektor operacji

W przykładzie QueryStringFormatter pokazano, jak punkty rozszerzalności programu Windows Communication Foundation (WCF) mogą służyć do zezwalania na dane komunikatów w innym formacie niż oczekiwano w programie WCF. Domyślnie formatery WCF oczekują, że parametry metody zostaną uwzględnione w elemecie soap:body . W przykładzie pokazano, jak zaimplementować niestandardowy formatator operacji, który analizuje dane parametrów z ciągu zapytania HTTP GET i wywołuje metody przy użyciu tych danych.

Przykład jest oparty na rozpoczynaniu pracy, która implementuje ICalculator kontrakt usługi. Pokazuje on, jak można zmienić komunikaty Dodawania, Odejmowania, Mnożenia i dzielenia, aby używać protokołu HTTP GET dla żądań klient-serwer i żądania HTTP POST z komunikatami POX dla odpowiedzi serwer-klient.

W tym celu przykład zawiera następujące informacje:

  • QueryStringFormatter, który implementuje IClientMessageFormatter i IDispatchMessageFormatter dla klienta i serwera, odpowiednio, i przetwarza dane w ciągu zapytania.

  • UriOperationSelector, który implementuje IDispatchOperationSelector na serwerze wykonywanie operacji wysyłania na podstawie nazwy operacji w żądaniu GET.

  • EnableHttpGetRequestsBehavior zachowanie punktu końcowego (i odpowiednia konfiguracja), które dodaje niezbędny selektor operacji do środowiska uruchomieniowego.

  • Pokazuje, jak wstawić nowy formater operacji do środowiska uruchomieniowego.

  • W tym przykładzie zarówno klient, jak i usługa to aplikacje konsolowe (.exe).

Uwaga

Procedura instalacji i instrukcje kompilacji dla tego przykładu znajdują się na końcu tego tematu.

Kluczowe pojęcia

QueryStringFormatter - Formater operacji jest składnikiem w programie WCF, który jest odpowiedzialny za konwertowanie komunikatu na tablicę obiektów parametrów i tablicę obiektów parametrów w komunikat. Odbywa się to na kliencie przy użyciu interfejsu IClientMessageFormatter i na serwerze z interfejsem IDispatchMessageFormatter . Te interfejsy umożliwiają użytkownikom uzyskiwanie komunikatów żądania i odpowiedzi z Serialize metod i Deserialize .

W tym przykładzie QueryStringFormatter implementuje oba te interfejsy i jest implementowany na kliencie i serwerze.

Żądanie:

  • W przykładzie użyto TypeConverter klasy do konwersji danych parametrów w komunikacie żądania do i z ciągów. Jeśli element TypeConverter nie jest dostępny dla określonego typu, przykładowy formater zgłasza wyjątek.

  • W metodzie IClientMessageFormatter.SerializeRequest na kliencie formater tworzy identyfikator URI z odpowiednim adresem To i dołącza nazwę operacji jako sufiks. Ta nazwa służy do wysyłania do odpowiedniej operacji na serwerze. Następnie pobiera tablicę obiektów parametrów i serializuje dane parametrów do ciągu zapytania identyfikatora URI przy użyciu nazw parametrów i wartości przekonwertowanych przez klasę TypeConverter . Właściwości To i Via są następnie ustawione na ten identyfikator URI. MessageProperties Dostęp do obiektu Properties jest uzyskiwany za pośrednictwem właściwości .

  • W metodzie IDispatchMessageFormatter.DeserializeRequest na serwerze formater pobiera Via identyfikator URI we właściwościach komunikatu żądania przychodzącego. Analizuje pary name-value w ciągu zapytania identyfikatora URI do nazw parametrów i wartości oraz używa nazw parametrów i wartości, aby wypełnić tablicę parametrów przekazanych do metody. Pamiętaj, że operacja wysyłania już wystąpiła, więc sufiks nazwy operacji jest ignorowany w tej metodzie.

Reakcja:

  • W tym przykładzie żądanie HTTP GET jest używane tylko dla żądania. Program formatujący deleguje wysyłanie odpowiedzi do oryginalnego formatującego, który zostałby użyty do wygenerowania komunikatu XML. Jednym z celów tego przykładu jest pokazanie, jak można zaimplementować taki formater delegowania.

UriPathSuffixOperationSelector, klasa

Interfejs IDispatchOperationSelector umożliwia użytkownikom implementowanie własnej logiki, dla której należy wysłać określony komunikat.

W tym przykładzie należy zaimplementować na serwerze, aby wybrać odpowiednią operację, UriPathSuffixOperationSelector ponieważ nazwa operacji jest uwzględniona w identyfikatorze URI HTTP GET zamiast nagłówka akcji w komunikacie. Przykład jest skonfigurowany tak, aby zezwalał tylko na nazwy operacji bez uwzględniania wielkości liter.

Metoda SelectOperation pobiera komunikat przychodzący i wyszukuje identyfikator URI we właściwościach komunikatu Via . Wyodrębnia sufiks nazwy operacji z identyfikatora URI, wyszukuje wewnętrzną tabelę, aby uzyskać nazwę operacji, do którego ma zostać wysłany komunikat, i zwraca tę nazwę operacji.

EnableHttpGetRequestsBehavior, klasa

Składnik UriPathSuffixOperationSelector można skonfigurować programowo lub za pomocą zachowania punktu końcowego. Przykład implementuje EnableHttpGetRequestsBehavior zachowanie określone w pliku konfiguracji aplikacji usługi.

Na serwerze:

Parametr OperationSelector jest ustawiony na implementację IDispatchOperationSelector .

Domyślnie program WCF używa filtru adresu dokładnego dopasowania. Identyfikator URI komunikatu przychodzącego zawiera sufiks nazwy operacji, po którym następuje ciąg zapytania zawierający dane parametrów, więc zachowanie punktu końcowego zmienia również filtr adresu jako filtr dopasowania prefiksu. W tym celu jest używany program WCFPrefixEndpointAddressMessageFilter .

Instalowanie modułów formatujących operacje

Zachowania operacji określające formatery są unikatowe. Jedno z takich zachowań jest zawsze implementowane domyślnie dla każdej operacji, aby utworzyć niezbędny formater operacji. Jednak te zachowania wyglądają jak tylko inne zachowanie operacji; nie są one możliwe do zidentyfikowania przez żaden inny atrybut. Aby zainstalować zachowanie zastępcze, implementacja musi wyszukać określone zachowania formatera zainstalowane przez moduł ładujący typu WCF domyślnie i zastąpić je lub dodać zgodne zachowanie do uruchomienia po zachowaniu domyślnym.

Te zachowania formatujące operacje można skonfigurować programowo przed wywołaniem CommunicationObject.Open lub przez określenie zachowania operacji wykonywanego po domyślnym. Nie można go jednak łatwo skonfigurować przez zachowanie punktu końcowego (a zatem przez konfigurację), ponieważ model zachowania nie zezwala na zachowanie w celu zastąpienia innych zachowań lub w inny sposób zmodyfikowania drzewa opisu.

Na kliencie:

Implementacja IClientMessageFormatter musi zostać zaimplementowana, aby można było przekonwertować żądania na żądania HTTP GET i delegować je do oryginalnego formatującego odpowiedzi. Odbywa się to przez wywołanie metody pomocniczej EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior .

Należy to zrobić przed wywołaniem metody 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);
}

Na serwerze:

  • Interfejs IDispatchMessageFormatter musi być zaimplementowany, aby można było odczytywać żądania HTTP GET i delegować do oryginalnego formatującego na potrzeby pisania odpowiedzi. Odbywa się to przez wywołanie tej samej EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior metody pomocniczej co klient (zobacz poprzedni przykładowy kod).

  • Należy to zrobić przed Open wywołaniem. W tym przykładzie pokazano, jak formatator jest modyfikowany ręcznie przed wywołaniem metody Open. Innym sposobem osiągnięcia tego samego celu jest utworzenie klasy, która ServiceHost wykonuje wywołania do EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior przed otwarciem (zobacz dokumentację hostingu i przykłady, aby zapoznać się z przykładami).

Środowisko użytkownika

Na serwerze:

  • Implementacja serwera ICalculator nie musi się zmieniać.

  • Plik App.config dla usługi musi używać niestandardowego powiązania POX, które ustawia messageVersion atrybut elementu textMessageEncoding na None.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    
  • Plik App.config dla usługi musi również określać niestandardowy, EnableHttpGetRequestsBehavior dodając go do sekcji rozszerzeń zachowania i używając go.

    <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>
    
  • Dodaj formatery operacji przed wywołaniem metody Open.

Na kliencie:

  • Implementacja klienta nie musi się zmieniać.

  • Plik App.config dla klienta musi używać niestandardowego powiązania POX, które ustawia messageVersion atrybut elementu textMessageEncoding na None. Jedną z różnic między usługą jest to, że klient musi włączyć ręczne adresowanie, aby można było zmodyfikować adres wychodzący Do.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport manualAddressing="True" />
        </binding>
      </customBinding>
    </bindings>
    
  • Plik App.config dla klienta musi określać ten sam niestandardowy EnableHttpGetRequestsBehavior , co serwer.

  • Dodaj formatery operacji przed wywołaniem metody CreateChannel().

Po uruchomieniu przykładu żądania operacji i odpowiedzi są wyświetlane w oknie konsoli klienta. Wszystkie cztery operacje (dodawanie, odejmowanie, mnożenie i dzielenie) musi zakończyć się powodzeniem.

Aby skonfigurować, skompilować i uruchomić przykład
  1. Upewnij się, że wykonano procedurę instalacji jednorazowej dla przykładów programu Windows Communication Foundation.

  2. Aby skompilować rozwiązanie, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).

  3. Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation.