Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'esempio Text illustra come implementare un codificatore di messaggi di testo personalizzato usando Windows Communication Foundation (WCF).
Il TextMessageEncodingBindingElement di WCF supporta solo le codifiche Unicode UTF-8, UTF-16 e big-endian. Il codificatore di messaggi di testo personalizzato in questo esempio supporta tutte le codifiche dei caratteri supportate dalla piattaforma che potrebbero essere necessarie per l'interoperabilità. L'esempio è costituito da un programma console client (.exe), da una libreria di servizi (.dll) ospitata da Internet Information Services (IIS) e da una libreria del codificatore di messaggi di testo (.dll). Il servizio implementa un contratto che definisce un modello di comunicazione request-reply. Il contratto è definito dall'interfaccia ICalculator, che espone operazioni matematiche (somma, sottrazione, moltiplicazione e divisione). Il client effettua richieste sincrone a una determinata operazione matematica e il servizio risponde con il risultato. Sia il client che il servizio usano anziché CustomTextMessageEncoder il valore predefinito TextMessageEncodingBindingElement.
L'implementazione del codificatore personalizzato è costituita da una factory del codificatore di messaggi, un codificatore di messaggi, un elemento di associazione di codifica dei messaggi e un gestore di configurazione e illustra quanto segue:
Creazione di un codificatore personalizzato e di una factory del codificatore.
Creazione di un elemento di associazione per un codificatore personalizzato.
Uso della configurazione dell'associazione personalizzata per l'integrazione di elementi di associazione personalizzati.
Sviluppo di un gestore di configurazione personalizzato per consentire la configurazione di file di un elemento di associazione personalizzato.
Per configurare, compilare ed eseguire l'esempio
Installare ASP.NET 4.0 usando il comando seguente.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enableAssicurati di aver eseguito la procedura di installazione di One-Time per gli esempi di Windows Communication Foundation.
Per compilare la soluzione, seguire le istruzioni riportate in Compilazione degli esempi di Windows Communication Foundation.
Per eseguire l'esempio in una configurazione con computer singolo o incrociato, seguire le istruzioni riportate in Esecuzione degli esempi di Windows Communication Foundation.
Message Encoder Factory e Message Encoder
Quando il canale client ServiceHost o il componente CustomTextMessageBindingElement della progettazione viene aperto, viene creato l'oggetto CustomTextMessageEncoderFactory. La fabbrica crea l'oggetto CustomTextMessageEncoder. Il codificatore di messaggi opera sia nella modalità di streaming che nella modalità memorizzata nel buffer. Usa il XmlReader e il XmlWriter rispettivamente per leggere e scrivere i messaggi. Anziché i lettori e i writer XML ottimizzati di WCF che supportano solo UTF-8, UTF-16 e Big-endian Unicode, questi lettori e writer supportano tutta la codifica supportata dalla piattaforma.
Nell'esempio di codice seguente viene illustrato 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();
}
}
Nell'esempio di codice seguente viene illustrato come creare la factory del codificatore di messaggi.
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;
}
}
}
Elemento di associazione della codifica dei messaggi
Gli elementi di associazione consentono la configurazione dello stack di runtime WCF. Per usare il codificatore di messaggi personalizzato in un'applicazione WCF, è necessario un elemento di associazione che crea la factory del codificatore messaggi con le impostazioni appropriate a livello appropriato nello stack di runtime.
Deriva CustomTextMessageBindingElement dalla BindingElement classe base ed eredita dalla MessageEncodingBindingElement classe . Ciò consente ad altri componenti WCF di riconoscere questo elemento di associazione come elemento di associazione di codifica dei messaggi. L'implementazione di CreateMessageEncoderFactory restituisce un'istanza della factory del codificatore di messaggi corrispondente con le impostazioni appropriate.
CustomTextMessageBindingElement espone le impostazioni per MessageVersion, ContentTypee Encoding tramite le proprietà . Il codificatore supporta sia le versioni Soap11Addressing che Soap12Addressing1. Il valore predefinito è Soap11Addressing1. Il valore predefinito di ContentType è "text/xml". La Encoding proprietà consente di impostare il valore della codifica dei caratteri desiderata. Il client e il servizio di esempio usano la codifica dei caratteri ISO-8859-1 (Latin1), che non è supportata da TextMessageEncodingBindingElement WCF.
Il codice seguente illustra come creare l'associazione a livello di codice usando il codificatore di messaggi di testo personalizzato.
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);
Aggiunta del supporto per i metadati all'elemento di binding per la codifica dei messaggi
Qualsiasi tipo che deriva da MessageEncodingBindingElement è responsabile dell'aggiornamento della versione dell'associazione SOAP nel documento WSDL generato per il servizio. A tale scopo, implementare il ExportEndpoint metodo nell'interfaccia IWsdlExportExtension e quindi modificare il file WSDL generato. In questo esempio usa CustomTextMessageBindingElement la logica di esportazione WSDL da TextMessageEncodingBindingElement.
Per questo esempio, la configurazione client è configurata a mano. Non è possibile utilizzare Svcutil.exe per generare la configurazione client perché non esporta un'asserzione CustomTextMessageBindingElement di criteri per descriverne il comportamento. È in genere consigliabile implementare l'interfaccia IPolicyExportExtension in un elemento di associazione personalizzato per esportare un'asserzione di criteri personalizzata che descrive il comportamento o la funzionalità implementata dall'elemento di associazione. Per un esempio di come esportare un'asserzione di criteri per un elemento di associazione personalizzato, vedere l'esempio Transport: UDP .
Gestore della configurazione del vincolo di codifica dei messaggi
La sezione precedente illustra come usare il codificatore di messaggi di testo personalizzato a livello di codice.
CustomTextMessageEncodingBindingSection implementa un gestore di configurazione che consente di specificare l'uso di un codificatore di messaggi di testo personalizzato all'interno di un file di configurazione. La CustomTextMessageEncodingBindingSection classe deriva dalla BindingElementExtensionElement classe . La BindingElementType proprietà informa il sistema di configurazione del tipo di elemento di associazione da creare per questa sezione.
Tutte le impostazioni definite da CustomTextMessageBindingElement vengono esposte come proprietà in CustomTextMessageEncodingBindingSection. Il ConfigurationPropertyAttribute aiuta a mappare gli attributi dell'elemento di configurazione alle proprietà e a impostare i valori predefiniti se l'attributo non è impostato. Dopo che i valori della configurazione vengono caricati e applicati alle proprietà del tipo, viene chiamato il CreateBindingElement metodo , che converte le proprietà in un'istanza concreta di un elemento di associazione.
Questo gestore di configurazione mappa alla seguente rappresentazione nel App.config o Web.config per il servizio o il client.
<customTextMessageEncoding encoding="utf-8" contentType="text/xml" messageVersion="Soap11Addressing1" />
L'esempio usa la codifica ISO-8859-1.
Per usare questo gestore di configurazione, è necessario registrarlo usando l'elemento di configurazione seguente.
<extensions>
<bindingElementExtensions>
<add name="customTextMessageEncoding" type="
Microsoft.ServiceModel.Samples.CustomTextMessageEncodingBindingSection,
CustomTextMessageEncoder" />
</bindingElementExtensions>
</extensions>