Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En el ejemplo texto se muestra cómo implementar un codificador de mensajes de texto personalizado mediante Windows Communication Foundation (WCF).
El TextMessageEncodingBindingElement de WCF solo admite las codificaciones UTF-8, UTF-16 y big-endian Unicode. El codificador de mensajes de texto personalizado de este ejemplo admite todas las codificaciones de caracteres compatibles con la plataforma que pueden ser necesarias para la interoperabilidad. El ejemplo consta de un programa de consola de cliente (.exe), una biblioteca de servicios (.dll) hospedada por Internet Information Services (IIS) y una biblioteca de codificadores de mensajes de texto (.dll). El servicio implementa un contrato que define un patrón de comunicación de solicitud-respuesta. El contrato se define mediante la ICalculator interfaz , que expone las operaciones matemáticas (Agregar, Restar, Multiplicar y Dividir). El cliente realiza solicitudes sincrónicas a una operación matemática determinada y el servicio responde con el resultado. Tanto el cliente como el servicio usan CustomTextMessageEncoder en lugar de TextMessageEncodingBindingElement predeterminado.
La implementación del codificador personalizado consta de un generador de codificadores de mensajes, un codificador de mensajes, un elemento de enlace de codificación de mensajes y un controlador de configuración, y muestra lo siguiente:
Creación de un codificador personalizado y un generador de codificadores.
Crear un elemento de enlace para un codificador personalizado.
Uso de la configuración de enlace personalizada para integrar elementos de enlace personalizados.
Desarrollar un controlador de configuración personalizado para permitir la configuración de archivos de un elemento de enlace personalizado.
Para configurar, compilar y ejecutar el ejemplo
Instale ASP.NET 4.0 con el comando siguiente.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enableAsegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.
Para compilar la solución, siga las instrucciones que se indican en Compilación de los ejemplos de Windows Communication Foundation.
Para ejecutar el ejemplo en una configuración de una sola máquina o de varias máquinas, siga las instrucciones que se indican en Ejecución de los ejemplos de Windows Communication Foundation.
Generador de codificadores de mensajes y codificador de mensajes
Cuando se abre ServiceHost o el canal de cliente, el componente de tiempo de diseño CustomTextMessageBindingElement crea CustomTextMessageEncoderFactory. El generador crea CustomTextMessageEncoder. El codificador de mensajes funciona tanto en el modo de streaming como en el modo almacenado en búfer. Usa el XmlReader y el XmlWriter para leer y escribir los mensajes respectivamente. En lugar de los lectores y escritores XML optimizados de WCF que solo admiten codificación compatible con UTF-8, UTF-16 y big-endian Unicode, estos lectores y escritores admiten todas las codificaciones compatibles con la plataforma.
En el ejemplo de código siguiente se muestra 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();
}
}
En el ejemplo de código siguiente se muestra cómo compilar el generador de codificadores de mensajes.
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 de enlace de codificación de mensajes
Los elementos de enlace permiten la configuración de la pila de ejecución de WCF. Para usar el codificador de mensajes personalizado en una aplicación WCF, se requiere un elemento de enlace que cree el generador de codificadores de mensajes con la configuración adecuada en el nivel adecuado en la pila en tiempo de ejecución.
CustomTextMessageBindingElement deriva de la BindingElement clase base y hereda de la MessageEncodingBindingElement clase . Esto permite que otros componentes de WCF reconozcan este elemento de enlace como un elemento de enlace de codificación de mensajes. La implementación de CreateMessageEncoderFactory devuelve una instancia de la factoría del codificador de mensajes coincidente con la configuración adecuada.
CustomTextMessageBindingElement expone la configuración de MessageVersion, ContentTypey Encoding a través de las propiedades . El codificador admite las versiones Soap11Addressing y Soap12Addressing1. El valor predeterminado es Soap11Addressing1. El valor predeterminado de ContentType es "text/xml". La Encoding propiedad permite establecer el valor de la codificación de caracteres deseada. El cliente y el servicio de ejemplo usan la codificación de caracteres ISO-8859-1 (Latin1), que no es compatible con WCF TextMessageEncodingBindingElement .
En el código siguiente se muestra cómo crear mediante programación el enlace mediante el codificador de mensajes de texto personalizado.
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);
Adición de compatibilidad de metadatos al elemento de enlace de la codificación de mensajes
Cualquier tipo derivado de MessageEncodingBindingElement es responsable de actualizar la versión del enlace SOAP en el documento WSDL generado para el servicio. Para ello, se implementa el ExportEndpoint método en la IWsdlExportExtension interfaz y, a continuación, se modifica el WSDL generado. En este ejemplo, el CustomTextMessageBindingElement utiliza la lógica de exportación de WSDL del TextMessageEncodingBindingElement.
Para este ejemplo, la configuración del cliente se configura manualmente. No puede usar Svcutil.exe para generar la configuración del cliente porque CustomTextMessageBindingElement no exporta una aserción de directiva para describir su comportamiento. Por lo general, debe implementar la IPolicyExportExtension interfaz en un elemento de enlace personalizado para exportar una aserción de directiva personalizada que describa el comportamiento o la funcionalidad implementados por el elemento de enlace. Para obtener un ejemplo de cómo exportar una aserción de directiva para un elemento de enlace personalizado, vea el ejemplo Transporte: UDP .
Controlador de configuración de enlace de codificación de mensajes
En la sección anterior se muestra cómo usar el codificador de mensajes de texto personalizado mediante programación.
CustomTextMessageEncodingBindingSection implementa un controlador de configuración que permite especificar el uso de un codificador de mensajes de texto personalizado dentro de un archivo de configuración. La CustomTextMessageEncodingBindingSection clase deriva de la BindingElementExtensionElement clase . La BindingElementType propiedad informa al sistema de configuración del tipo de elemento de enlace que se va a crear para esta sección.
Todas las opciones definidas por CustomTextMessageBindingElement se exponen como las propiedades de CustomTextMessageEncodingBindingSection. El ConfigurationPropertyAttribute ayuda a asignar los atributos del elemento de configuración a las propiedades y a establecer valores predeterminados si no se ha establecido el atributo. Una vez cargados y aplicados los valores de la configuración a las propiedades del tipo , CreateBindingElement se llama al método , que convierte las propiedades en una instancia concreta de un elemento de enlace.
Este controlador de configuración asigna a la representación siguiente en App.config o Web.config para el servicio o cliente.
<customTextMessageEncoding encoding="utf-8" contentType="text/xml" messageVersion="Soap11Addressing1" />
En el ejemplo se usa la codificación ISO-8859-1.
Para usar este controlador de configuración, debe registrarse mediante el siguiente elemento de configuración.
<extensions>
<bindingElementExtensions>
<add name="customTextMessageEncoding" type="
Microsoft.ServiceModel.Samples.CustomTextMessageEncodingBindingSection,
CustomTextMessageEncoder" />
</bindingElementExtensions>
</extensions>