Continuo con VS2008, con WCF (Windows Communication Foundation), en este caso integrando WCF con JAVA y más concretamente con una aplicación desarrollada en AXIS 1.1.0.xxx, vamos, “una patata” un problema, puesto que es la primera y obsoleta versión, no cumple muchos puntos del estandard WSDL, el principal es que no permite las cláusulas <import>, es decir, es necesario generar un WSDL “to junto”, en fin, cosas del directo como se suele decir, jeje…
Para conocer como afrontar este inconveniente, os cuento lo que he hecho:
Se trata de crear una extensión para nuestro WCF y en cierta forma dotarlo de una nueva funcionalidad, para ello usaremos los interfaces; IWsdlExportExtension, IEndpointBehavior. Entrando más en detalle, necesitaremos añadir código al evento ExportEndPoint de IWsdlExportExtension tal y como muestro a continuación:
public void ExportEndpoint( WsdlExporter exporter, WsdlEndpointConversionContext context ) { XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas; foreach (WsdlDescription wsdl in exporter.GeneratedWsdlDocuments) { List<XmlSchema> importsList = new List<XmlSchema>(); foreach (XmlSchema schema in wsdl.Types.Schemas) { AddImportedSchemas(schema, schemaSet, importsList); } wsdl.Types.Schemas.Clear(); foreach (XmlSchema schema in importsList) { RemoveXsdImports(schema); wsdl.Types.Schemas.Add(schema); } } } private void AddImportedSchemas( XmlSchema schema, XmlSchemaSet schemaSet, List<XmlSchema> importsList ) { foreach (XmlSchemaImport import in schema.Includes) { ICollection realSchemas = schemaSet.Schemas(import.Namespace); foreach (XmlSchema ixsd in realSchemas) { if (!importsList.Contains(ixsd)) { importsList.Add(ixsd); AddImportedSchemas(ixsd, schemaSet, importsList); } } } } private void RemoveXsdImports(XmlSchema schema) { for (int i = 0; i < schema.Includes.Count; i++) { if (schema.Includes[i] is XmlSchemaImport) schema.Includes.RemoveAt(i--); } }
El resto de métodos a sobrescribir podrán dejarse vacíos.
Adicionalmente y para poder configurar nuestro WCF con la herramienta de configuración (WCF Service Configuration Editor), será necesario:
public class InlineXsdBehaviorSection : BehaviorExtensionElement { protected override object CreateBehavior() { return new InlineXsdInWsdlBehavior(); } public override Type BehaviorType { get { Type t = Type.GetType("MyProject.WCF.Extensions.InlineXsdInWsdlBehavior"); return t; } } }
Finalmente tendremos que incluir esta DLL en el GAC, creando previamente un Strong Key, o bien, incluir la referencia en nuestro proyecto, con “Copy Local = true”. Al menos durante el desarrollo os recomiendo que la incluyais en el GAC, evitará el estar constantemente seleccionando esta dll cada vez que editamos la configuración con el “WCF Service Configuration Editor”, “menuda lata, ¿no?”.
Para poner en marcha nuestro WCF:
- Configurar el WS de forma normal
- Cargar la nueva funcionalidad, para ello:
- Abrir el editor y en el árbol de configuración (a la izquierda), desplegar”Advanced – Extensions”
- seleccionar “behavior element extensions”.
- En la ventana de la derecha crear un nuevo elemento, Click en “New…”
- Buscar y seleccionar nuestra DLL y asignar un nombre.
- Crear un nuevo “Endpoint Behavior”.
- Seleccionar “Advanced – Endpoint Behavior” en el árbol de configuración y crear (“Add…”) un nuevo elemento.
- El el siguiente cuadro de diálogo buscar y seleccionar el nombre dado a nuestra DLL.
- Por último, asociar la nueva extensión a nuestro EndPoint:
- seleccionar “Services – MyProject.WCF.Extensions.InlineXsdInWsdlBehavior – EndPoints – MyEndpoint”
- Asignar el Endpoint beavior a nuestro servicio dando valor la la propiedad “BehaviorConfiguration”
Si ahora comprobamos el WSDL de nuestro WCF veremos como ya no incluye ninguna clausula “import”.
Esto no es del todo cierto, jejeje… existe un inconveniente/restricción y dependerá de los Namespaces de nuestras clases, es decir, será necesario que todos los Namespaces sean iguales, vamos, que sólo exista un único Namespace. Para ver como cambiar el namespace, echad un vistazo a este otro post; “tempuri.org con WCF“.
Para mayor detalle y comprensión sobre los behaviors, os sugiero que le echéis un vistazo a un artículo de la MSDN Magazine de Diciembre de 2007: http://msdn.microsoft.com/msdnmag/issues/07/12/ServiceStation/default.aspx?loc=es
Nota: Para el siguiente post contaré sobre “ASP NET Compatibility” y lo que ofrece sobre todo a aquellos que estamos empezando con WCF.
Saludos y suerte en vuestras nuevas extensiones
Juanlu