WCF
publicado enIIS
que consumirán clientes de cualquier plataforma (principalmente java) y al configurar desdeIIS
que el servicio solo responderá a peticiones https los clientes java dejan de funcionar (asumimos que han modificado la URL http por https).Sabemos que
WCF
se basa en el protocolo soap y que W3C define las reglas y estas van evolucionando. Actualmente la versión más reciente del estandarsoap
es la 1.2. En un mundo ideal cuando se plantea un proyecto de este tipo a nivel empresarial ambas partes responsables de cada plataforma deberían establecer el estandar por el que se regirán o si más no debería estar estipulado en algún tipo de documento. En el mundo real no siempre es así y se pueden dar situaciones de "imcompatibilidad" entre servicio y cliente. Este tipo de situaciones suele darse porqueWCF
se basa en el estándar soap 1.2 (W3C) pero el uso de herramientas tanto Java como Microsoft que se basan en soap 1.1 siguen estando bastante extendidas en estos momentos y depedendiendo del escenario es complicado determinar quien debería adaptarse a quien si no está especificado en la definición del proyecto. En este caso por lógica el servidor es 1 y los clientes son N por tanto es más eficiente hacer compatibleWCF
consoap
1.1 que no obligar a nuestros clientes a adaptarse a 1.2.Nos alejamos del debate de quien sigue o no el estandar y nos centramos en como solucionar el problema que se plantea en el escenario inicial. Algunos clientes se quejan que hay un nodo más en el
wsdl
que su cliente 1.1 no entiende desde que hemos configurado el tráfico seguro enIIS
, es el nodoWsa:Policy
. La versión 1.2 permite a través de este nodo definir en el documentowsdl
que tipo de seguridad tiene configurada el servicio a nivel de transporte y mensaje por tanto al configurar https enIIS
se añaden automáticamente los nodos correspondientes al wsdl.Una solución es eliminar el nodo problemático, para ello es interesante saber que la clase del Framework que se encarga de generar el documento wsdl de nuestro servicio es
WsdlExporter
y que podemos suplantarla para manipular los nodos del documentowsdl
que publicamos.Veamos como hacerlo, en primer lugar crearemos una clase AreaTICWsdlExporter:
namespace areaTIC.WCF
{
public class AreaTICWsdlExporter : WsdlExporter
{
public override void ExportContract(ContractDescription contract)
{
base.ExportContract(contract);
}
public override void ExportEndpoint(ServiceEndpoint endpoint)
{
base.ExportEndpoint(endpoint);
}
public override MetadataSet GetGeneratedMetadata()
{
MetadataSet md = base.GetGeneratedMetadata();
//adaptamos wsdl al formato que espera que el cliente java eliminando los nodos que están generando conflicto entre plataformas;
System.Web.Services.Description.ServiceDescription sd = (System.Web.Services.Description.ServiceDescription)md.MetadataSections[0].Metadata;
sd.Bindings[0].Extensions.RemoveAt(0);
if (sd.Bindings.Count > 0)
{
if (sd.Bindings[0].Extensions.Count > 0)
{
SoapBinding ele = (SoapBinding)sd.Bindings[0].Extensions[0];
ele.Style = SoapBindingStyle.Document;
ServiceDescriptionCollection a = base.GeneratedWsdlDocuments;
a[0].Extensions.RemoveAt(0);
}
}
return md;
}
}
}
El siguiente paso será suplantar WsdlExporter
en el servicio conflictivo para ello necesitaremos tener control de la instanciaServiceHost
de nuestro servicio. En este artículo explica como controlar la instacia deServiceHost
en IIS usandoServiceHostFactory
. Una vez tengamos configurado ServiceHostFactory tendremos que añadir en el método CreateServiceHost el código para suplantarWsdlExporter
por el nuestro personalizado.
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
switch (serviceType.Name)
{
case "ServicioConflictivo":
ServiceMetadataBehavior smb = customServiceHost.Description.Behaviors.Find();
smb.MetadataExporter = new DgestWsdlExporter();
break;
}
}
Hasta aquí el artículo, si tenéis alguna duda o queréis hacer algún comentario no os cortéis. También podéis seguir
No hay comentarios:
Publicar un comentario en la entrada