2011-06-01 7 views
6

He creado un servicio web WCF en C# implementado en un EXE de servicio de Windows que funciona en gran medida del modo que yo quiero. Lo estoy usando de manera autohospedada (no dentro de IIS).Confundido por el uso del nombre de host en el archivo WSDL en el servicio web C#

Para hacer que un archivo WSDL esté disponible para el servicio web Java que llama, agregué ServiceMetadataBehavior a la creación del host. es decir:

ServiceHost host = new ServiceHost(typeof(MyService)); 
ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 
smb.HttpGetEnabled = true; 
host.Description.Behaviors.Add(smb); 
host.Open(); 

Todo funcionó bien hasta que cambie mi servicio a otro servidor con un nombre de host diferente. Cuando me conecto al WSDL (http: // prod-server: 55000/MyService? Wsdl), veo que el nombre de host del servidor de desarrollo está codificado en el WSDL.

Aquí hay un fragmento del WSDL como se ve en un navegador:

<wsdl:definitions name="MyService" targetNamespace="http://tempuri.org/"> 
<wsdl:import namespace="MyProject.ServiceContracts" location="http://dev-server:55000/MyService?wsdl=wsdl0"/> 
<wsdl:types/> 

He comprobado todo el código C# en el proyecto, y el nombre del servidor de desarrollo no está codificado en cualquier lugar.

En el archivo app.config, tengo el siguiente definido:

<system.serviceModel> 
<services> 
    <service name="MyService"> 
    <endpoint address="http://localhost:55000/MyService" binding="basicHttpBinding" 
     bindingConfiguration="" contract="MyProject.ServiceContracts.IMyInterface" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:55000/MyService" /> 
     </baseAddresses> 
    </host> 
    </service> 
</services> 

Yo esperaría que esto daría como resultado el nombre de la máquina localhost ser sustituido, pero persiste como la caja de desarrollo nombre en el cual el servicio fue originalmente creado/desplegado. ¿Estoy equivocado?

También busqué la posibilidad de especificar explícitamente una ruta a mi archivo WSDL, pero por lo que puedo deducir, esto solo se puede hacer si se aloja el servicio en IIS.

Por último y puramente por curiosidad, me pregunto si realmente se crea un archivo WSDL real (quiero decir, un archivo físico en el disco) o si se representa dinámicamente con cada solicitud.

+1

Tenga en cuenta que el nombre de host en el WSDL es solo una pista. No pretende ser la URL del punto final, necesariamente. Se espera que el cliente configure la URL del punto final con el que desea comunicarse. –

Respuesta

3

Se crea dinámicamente, no en todas las llamadas IIRC, sino en la primera solicitud al punto final de los metadatos. No estoy seguro de por qué está viendo el nombre de su servidor DEV en la máquina que no es DEV, pero, debido a que está especificando localhost solo en su dirección de punto final, resolverá el DNS utilizando la dirección de red primaria para el servidor. Es posible que desee considerar agregar el comportamiento useRequestHeadersForMetadataAddress a su configuración para que el DNS con el que se accede al servicio se utilice realmente en su lugar.

+0

Esto parece haber hecho el truco para mí. ¡Gracias un montón! – Javawanabe

3

Con WCF, el WSDL se genera dinámicamente.

He tenido este problema varias veces en un servicio WCF 3/3.5 cuando necesitaba enviar un WSDL a alguien como un archivo. Por lo general, lo que hago es guardar los archivos (normalmente hay 3, un wsdl para el servicio, un xsd para sus tipos y un xsd para los tipos .net, pero su millaje puede variar) y luego actualizar manualmente las importaciones wsdl para referenciar los otros dos archivos relativos al archivo wsdl, luego envíe los tres archivos.

El wsdl:service, wsdl:port y soap:address seguirá habiendo hacer referencia al servidor de dev, pero la mayoría de las bibliotecas de cliente WS dar cuenta de esto y permitir que el desarrollador para configurar el punto final.

+0

OK - tal vez estoy confundido cuando realmente se necesita WSDL. ¿Solo se hace referencia en el momento en que el código de llamada genera los objetos proxy o con cada llamada? – Javawanabe

+1

@Javawanabe: Depende de qué biblioteca de Soap estés usando. Algunas bibliotecas necesitan el wsdl para generar el cliente cada vez que se inicia la aplicación (se viene a la mente nusoap para php), pero algunas bibliotecas (asmx, por ejemplo) solo lo necesitan para generar el cliente en el momento del diseño. Si su meta es una velocidad y eficiencia óptimas, entonces usaría una biblioteca que descifra el WSDL en el momento del diseño y luego solo envía solicitudes/publicaciones al punto final en el tiempo de ejecución. – Brook

+0

Hay opciones provistas por WCF para controlar esto específicamente. No hay ninguna razón para ir con archivos WSDL difíciles solo para resolver este problema. –

Cuestiones relacionadas