Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W przykładzie Text pokazano, jak zaimplementować niestandardowy koder komunikatów tekstowych przy użyciu programu Windows Communication Foundation (WCF).
Program TextMessageEncodingBindingElement WCF obsługuje tylko kodowanie UTF-8, UTF-16 i big-endian Unicode. Niestandardowy koder komunikatów tekstowych w tym przykładzie obsługuje wszystkie kodowania znaków obsługiwane przez platformę, które mogą być wymagane do współdziałania. Przykład składa się z programu konsolowego klienta (.exe), biblioteki usług (.dll) hostowanej przez usługi Internet Information Services (IIS) oraz biblioteki kodera komunikatów tekstowych (.dll). Usługa implementuje kontrakt, który definiuje wzorzec komunikacji typu żądanie-odpowiedź. Kontrakt jest definiowany przez ICalculator interfejs, który uwidacznia operacje matematyczne (Dodawanie, Odejmowanie, Mnożenie i Dzielenie). Klient wysyła synchroniczne żądania do danej operacji matematycznej, a usługa odpowiada z wynikiem. Zarówno klient, jak i usługa używają CustomTextMessageEncoder zamiast domyślnej TextMessageEncodingBindingElement.
Implementacja kodera niestandardowego składa się z fabryki kodera komunikatów, kodera komunikatów, elementu wiązania kodowania komunikatów i procedury obsługi konfiguracji oraz przedstawia następujące funkcje:
Tworzenie niestandardowego enkodera i fabryki enkoderów.
Tworzenie elementu powiązania dla kodera niestandardowego.
Używanie niestandardowej konfiguracji powiązania do integrowania niestandardowych elementów powiązania.
Tworzenie niestandardowego modułu konfiguracji, aby umożliwić konfigurację za pomocą pliku dla niestandardowego elementu powiązania.
Aby skonfigurować, skompilować i uruchomić przykładowy program
Zainstaluj ASP.NET 4.0 przy użyciu następującego polecenia.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enableUpewnij się, że wykonano procedurę instalacji One-Time dla przykładów programu Windows Communication Foundation.
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).
Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w Uruchamianie przykładów programu Windows Communication Foundation.
Fabryka enkoderów komunikatów i enkoder komunikatów
Gdy ServiceHost lub kanał klienta jest otwarty, składnik CustomTextMessageBindingElement czasu projektowania tworzy element CustomTextMessageEncoderFactory. Fabryka tworzy obiekt CustomTextMessageEncoder. Koder komunikatów działa zarówno w trybie przesyłania strumieniowego, jak i w trybie buforowania. Używa odpowiednio poleceń XmlReader i XmlWriter do odczytywania i zapisywania komunikatów. W przeciwieństwie do zoptymalizowanych czytników XML i pisarzy WCF, które obsługują tylko kodowanie UTF-8, UTF-16 i big-endian Unicode, te czytniki i pisarze obsługują wszystkie kodowania obsługiwane przez platformę.
Poniższy przykład kodu przedstawia element CustomTextMessageEncoder.
public class CustomTextMessageEncoder : MessageEncoder
{
private CustomTextMessageEncoderFactory factory;
private XmlWriterSettings writerSettings;
private string contentType;
public CustomTextMessageEncoder(CustomTextMessageEncoderFactory factory)
{
this.factory = factory;
this.writerSettings = new XmlWriterSettings();
this.writerSettings.Encoding = Encoding.GetEncoding(factory.CharSet);
this.contentType = $"{this.factory.MediaType}; charset={this.writerSettings.Encoding.HeaderName}";
}
public override string ContentType
{
get
{
return this.contentType;
}
}
public override string MediaType
{
get
{
return factory.MediaType;
}
}
public override MessageVersion MessageVersion
{
get
{
return this.factory.MessageVersion;
}
}
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
byte[] msgContents = new byte[buffer.Count];
Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);
bufferManager.ReturnBuffer(buffer.Array);
MemoryStream stream = new MemoryStream(msgContents);
return ReadMessage(stream, int.MaxValue);
}
public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
{
XmlReader reader = XmlReader.Create(stream);
return Message.CreateMessage(reader, maxSizeOfHeaders, this.MessageVersion);
}
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
MemoryStream stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
message.WriteMessage(writer);
writer.Close();
byte[] messageBytes = stream.GetBuffer();
int messageLength = (int)stream.Position;
stream.Close();
int totalLength = messageLength + messageOffset;
byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
return byteArray;
}
public override void WriteMessage(Message message, Stream stream)
{
XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
message.WriteMessage(writer);
writer.Close();
}
}
Poniższy przykład kodu pokazuje, jak utworzyć fabrykę kodera komunikatów.
public class CustomTextMessageEncoderFactory : MessageEncoderFactory
{
private MessageEncoder encoder;
private MessageVersion version;
private string mediaType;
private string charSet;
internal CustomTextMessageEncoderFactory(string mediaType, string charSet,
MessageVersion version)
{
this.version = version;
this.mediaType = mediaType;
this.charSet = charSet;
this.encoder = new CustomTextMessageEncoder(this);
}
public override MessageEncoder Encoder
{
get
{
return this.encoder;
}
}
public override MessageVersion MessageVersion
{
get
{
return this.version;
}
}
internal string MediaType
{
get
{
return this.mediaType;
}
}
internal string CharSet
{
get
{
return this.charSet;
}
}
}
Element powiązania dla kodowania wiadomości
Elementy wiążące umożliwiają konfigurację stosu uruchomieniowego WCF. Aby używać niestandardowego kodera komunikatów w aplikacji WCF, wymagany jest element powiązania, który tworzy fabrykę kodera komunikatów z odpowiednimi ustawieniami na odpowiednim poziomie w stosie środowiska uruchomieniowego.
Element CustomTextMessageBindingElement pochodzi z klasy bazowej BindingElement i dziedziczy z MessageEncodingBindingElement klasy . Dzięki temu inne składniki programu WCF mogą rozpoznawać ten element powiązania jako element powiązania kodowania komunikatów. Implementacja CreateMessageEncoderFactory zwraca wystąpienie zgodnej fabryki kodera komunikatów z odpowiednimi ustawieniami.
Ustawienia dla CustomTextMessageBindingElement, MessageVersion i ContentType są udostępniane poprzez właściwości Encoding. Koder obsługuje wersje Soap11Addressing i Soap12Addressing1. Wartość domyślna to Soap11Addressing1. Wartość domyślna to ContentType "text/xml". Właściwość Encoding umożliwia ustawienie wartości żądanego kodowania znaków. Przykładowy klient i usługa używają kodowania znaków ISO-8859-1 (Latin1), które nie jest obsługiwane przez WCF.
Poniższy kod pokazuje, jak programowo utworzyć powiązanie przy użyciu niestandardowego kodera komunikatów tekstowych.
ICollection<BindingElement> bindingElements = new List<BindingElement>();
HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();
CustomTextMessageBindingElement textBindingElement = new CustomTextMessageBindingElement();
bindingElements.Add(textBindingElement);
bindingElements.Add(httpBindingElement);
CustomBinding binding = new CustomBinding(bindingElements);
Dodawanie obsługi metadanych do elementu powiązania kodowania komunikatów
Każdy typ pochodzący z MessageEncodingBindingElement jest odpowiedzialny za aktualizowanie wersji powiązania SOAP w dokumencie WSDL wygenerowanym dla usługi. Jest to realizowane przez zaimplementowanie ExportEndpoint metody w interfejsie IWsdlExportExtension , a następnie zmodyfikowanie wygenerowanego pliku WSDL. W tym przykładzie CustomTextMessageBindingElement korzysta z logiki eksportu WSDL z TextMessageEncodingBindingElement.
W tym przykładzie konfiguracja klienta jest ręcznie skonfigurowana. Nie można użyć Svcutil.exe do wygenerowania konfiguracji klienta, ponieważ CustomTextMessageBindingElement nie eksportuje asercji zasad w celu opisania jego zachowania. Interfejs IPolicyExportExtension należy zazwyczaj zaimplementować w niestandardowym elemencie powiązania, aby wyeksportować niestandardową deklarację polityki opisującą zachowanie lub możliwość implementowaną przez element powiązania. Przykład eksportowania asercji zasad dla niestandardowego elementu powiązania można zobaczyć w przykładzie Transport: UDP.
Moduł konfiguracji wiązań kodowania komunikatów
W poprzedniej sekcji pokazano, jak programowo używać niestandardowego kodera komunikatów tekstowych.
CustomTextMessageEncodingBindingSection implementuje mechanizm obsługi konfiguracji, który pozwala na wykorzystanie niestandardowego kodera wiadomości tekstowych w pliku konfiguracyjnym. Klasa CustomTextMessageEncodingBindingSection pochodzi z BindingElementExtensionElement klasy . Właściwość BindingElementType informuje system konfiguracji o typie elementu powiązania, który ma zostać utworzony dla tej sekcji.
Wszystkie ustawienia zdefiniowane przez CustomTextMessageBindingElement są dostępne jako właściwości w CustomTextMessageEncodingBindingSection.
ConfigurationPropertyAttribute pomaga w mapowaniu atrybutów elementu konfiguracji na właściwości oraz w ustawianiu wartości domyślnych, jeśli atrybut nie jest ustawiony. Po załadowaniu i zastosowaniu wartości z konfiguracji do właściwości typu CreateBindingElement wywoływana jest metoda, która konwertuje właściwości na konkretne wystąpienie elementu powiązania.
Ten moduł konfiguracji odpowiada następującej reprezentacji w App.config lub Web.config w przypadku usługi lub klienta.
<customTextMessageEncoding encoding="utf-8" contentType="text/xml" messageVersion="Soap11Addressing1" />
W przykładzie użyto kodowania ISO-8859-1.
Aby użyć tej procedury obsługi konfiguracji, należy ją zarejestrować przy użyciu następującego elementu konfiguracji.
<extensions>
<bindingElementExtensions>
<add name="customTextMessageEncoding" type="
Microsoft.ServiceModel.Samples.CustomTextMessageEncodingBindingSection,
CustomTextMessageEncoder" />
</bindingElementExtensions>
</extensions>