visual tutorial studio ejemplo consumir c# .net wcf

c# - tutorial - A veces, agregar una referencia de servicio WCF genera una referencia vacía.cs



wcf tutorial (13)

A veces, agregar una referencia de servicio WCF genera una reference.cs vacía y no puedo hacer referencia al servicio en ninguna parte del proyecto.

¿Alguien ha encontrado esto?


Como señala @dblood, el principal problema está en DataContractSerializer, que no reutiliza correctamente los tipos. Ya hay algunas respuestas aquí, así que comenzaré añadiendo algunas ventajas y desventajas sobre esto:

  • El indicador ''IsReference'' causa muchos problemas, pero eliminarlo no siempre es la respuesta (específicamente: en situaciones con recursividad).
  • El problema subyacente es que el contrato de datos de alguna manera no es lo mismo que los nombres de los tipos, aunque a veces lo son (¿eh? Sí, lo leíste bien). Aparentemente, el serializador es bastante exigente y es muy difícil encontrar el verdadero problema.
  • Eliminar las ''verificaciones de referencias'' de la ''Configurar referencia de servicio'' funciona, pero te deja con múltiples implementaciones. Sin embargo, a menudo reutilizo las interfaces SOAP en las DLL. Además, en las SOA más maduras que conozco, las interfaces de servicios múltiples implementan y amplían las mismas clases de interfaz. La eliminación de los controles de "usar tipos de referencia" da como resultado una situación en la que ya no puede simplemente pasar objetos.

Afortunadamente, si tiene el control de su servicio, existe una solución simple que resuelve todos estos problemas. Esto significa que aún puede volver a utilizar las interfaces de servicio en las DLL, que es IMO imprescindible para una solución adecuada. Así es como funciona la solución:

  1. Cree una DLL de interfaz separada. En esa DLL, incluya todos los DataContract y ServiceContract; poner ServiceContract en sus interfaces.
  2. Derive la implementación del servidor desde la interfaz.
  3. Use la misma DLL para construir el cliente usando su método favorito. Por ejemplo (IMyInterface es la interfaz de contrato de servicio):

    var httpBinding = new BasicHttpBinding(); var identity = new DnsEndpointIdentity(""); var address = new EndpointAddress(url, identity, new AddressHeaderCollection()); var channel = new ChannelFactory<IMyInterface>(httpBinding, address); return channel.CreateChannel();

En otras palabras: no use la funcionalidad ''agregar referencia de servicio'' , pero obligue a WCF a utilizar los tipos de servicio (correctos) evitando la generación de proxy. Después de todo, ya tienes estas clases.

Pro:

  1. Evita el proceso svcutil.exe, lo que significa que no tiene problemas con IsReference
  2. Los nombres y los tipos de DataContract son correctos por definición; después de todo, tanto el servidor como el cliente usan la misma definición.
  3. Si extiende la API o utiliza tipos de otra DLL, (1) y (2) todavía se mantienen, por lo que no se ejecutará ningún problema allí.

Contras:

  1. Los métodos de sincronización A son un problema, ya que no se genera un proxy a-sync. Como resultado, no recomendaría hacer esto en las aplicaciones de Silverlight.

Como señala la respuesta aceptada, un problema de referencia de tipo cuando se reutilizan tipos es probablemente el culpable. Encontré que cuando no se puede determinar fácilmente el problema, usar la línea de comando svcutil.exe lo ayudará a revelar el problema subyacente (como señala John Saunders).

Como una mejora aquí hay un ejemplo rápido del uso de svcutil.

svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:/MyCode/MyAssembly/bin/debug/MyAssembly.dll"

Dónde:

  • / t: el código genera el código de una URL determinada
  • / d: para especificar el directorio para la salida
  • / r: para especificar un conjunto de referencia

Referencia completa de la línea de comandos de svcutil aquí: http://msdn.microsoft.com/en-us/library/aa347733.aspx

Una vez que ejecute svcutil, debería ver la excepción lanzada por la importación. Puede recibir este tipo de mensaje sobre uno de sus tipos: "el tipo al que se hace referencia no se puede usar porque no coincide con DataContract importado".

Esto podría ser simplemente como se especifica en que hay una diferencia en uno de los tipos en el ensamblado al que se hace referencia de lo que se generó en el DataContract para el servicio. En mi caso, el servicio que estaba importando tenía tipos más nuevos y actualizados de los que tenía en el ensamblado compartido. Esto no fue aparente porque el tipo mencionado en la excepción parecía ser el mismo. Lo que era diferente era uno de los tipos complejos anidados usados ​​por el tipo.

Existen otros escenarios más complejos que pueden desencadenar este tipo de excepción y los reference.cs blancos resultantes. Aquí hay un ejemplo .

Si está experimentando este problema y no está utilizando tipos genéricos en sus contratos de datos ni está utilizando IsReference = true, entonces le recomiendo verificar con certeza que sus tipos compartidos son exactamente los mismos en su cliente y servidor. De lo contrario, es probable que se encuentre con este problema.


Cuando esto suceda, busque en la ventana Errores y en la ventana Salida para ver si hay algún mensaje de error. Si eso no funciona, intente ejecutar svcutil.exe manualmente y vea si hay algún mensaje de error.


Generalmente encuentro que es un problema de código genérico y la mayoría de las veces es porque tengo un conflicto de nombre de tipo que no puede resolver.

Si hace clic derecho en su referencia de servicio y hace clic en configurar y desmarcar "Tipos de reutilización en ensambles referenciados", es probable que resuelva el problema.

Si estaba utilizando algún aspecto de esta función, es posible que deba asegurarse de que sus nombres estén limpios.


He encontrado que esto ocurre comúnmente cada vez que agrego una referencia, la elimino y luego vuelvo a agregar un servicio con el mismo nombre. Los conflictos de tipo parecen ser causados ​​por los viejos archivos que quedan en algún lugar que Visual Studio aún puede ver. Todo lo que tengo que hacer para solucionarlo es una limpieza antes de agregar la nueva referencia.

  1. Elimine la referencia de servicio con problemas.
  2. Haga clic en el nombre del proyecto en el Explorador de soluciones para resaltar el proyecto.
  3. Haga clic derecho en la referencia del proyecto.
  4. Cerca de la parte superior de la lista de contexto, haga clic en el elemento Limpiar .
  5. Agregue su referencia de servicio como lo haría normalmente.

Espero que esto ayude.


La técnica que funcionó para mí en mi caso, después de leer estas respuestas en vano, fue simplemente para comentar todo mi contrato, y descomentar bits hasta que ya no funciona, de forma binaria. Eso reduce el bit ofensivo del código.

Entonces solo tienes que adivinar qué está mal con ese código.

Algunos comentarios de error en la herramienta habrían ayudado, por supuesto.

Estoy escribiendo un contrato de servicio web. Tenía una enumeración de marcador de posición sin miembros. Está bien. Pero si lo uso en una propiedad de otra clase y reutilizo el dll del contrato en el cliente, el codegen explota sin mensaje de error. Ejecutar svcutil.exe no ayudó, simplemente no produjo un archivo cs sin mencionar por qué.


Lo siguiente no se incluye aquí, y fue la solución que adopté (SvcUtils fue útil para ver el mensaje de error. Sin embargo, el error que obtuve fue que el wrapper type message cannot be projected as a data contract type since it has multiple namespaces . Seguí esta pista, y aprendí sobre wsdl.exe través de this publicación).

En mi caso, simplemente al ejecutar wsdl [ my-asmx-service-address ] se generó un archivo .cs sin problemas, que incluí en mi proyecto e instalé para usar el servicio.


Me enfrenté a un problema similar ayer durante el desarrollo. Descubrí que estaba usando el mismo espacio de nombres en 2 versiones diferentes de contratos.

Tenemos 2 versiones de contratos, por ejemplo, versión 4 y versión 5. Copié todos los contratos de la versión 4 y renombré todo el espacio de nombres de la versión4 a la versión5. Al hacer esto, olvidé cambiar el nombre del espacio de nombres de v4 a v5 en uno de los archivos. Debido al conflicto del espacio de nombres, el archivo Reference.cs estaba vacío.

Este problema es difícil de solucionar ya que no aparece ningún mensaje de error al generar la referencia de servicio. Para identificar este problema, validaba manualmente todos los nuevos archivos que había creado. Hay otras formas de resolver este problema. Este es el primer paso que debe realizar antes de buscar otras opciones.


Me he estado golpeando la cabeza por un día entero con este problema exacto. Lo acabo de arreglar. Así es cómo...

El servicio tuvo que ejecutarse a través de SSL (es decir, está en https://mydomain.com/MyService.svc )

Agregar una referencia de servicio al servicio WCF en un servidor de desarrollo funcionó bien.

La implementación exacta de la misma compilación del servicio WCF en el servidor de producción en vivo, el cambio a la aplicación cliente y la configuración de la referencia de servicio para apuntar al servicio en vivo no mostraron errores, pero la aplicación no se compiló: resulta que la referencia del servicio ¡El archivo Reference.cs estaba completamente vacío! La actualización de la referencia de servicio no hizo diferencia. La limpieza de la solución no ayudó. Reiniciar VS2010 no hizo diferencia. Crear una nueva solución en blanco, iniciar un proyecto de consola y agregar una referencia de servicio al servicio en vivo mostró exactamente el mismo problema.

No pensé que se debía a tipos conflictivos ni a nada, pero qué demonios: reconfiguré la referencia del servicio WCF desmarcando "Reutilizar tipos en todos los ensamblados a los que se hace referencia". Sin alegría; Devolví la marca de verificación.

El siguiente paso fue probar svcutil en la URL de referencia para ver si eso ayudaría a descubrir el problema. Aquí está el comando:

svcutil /t:code https://mydomain.com/MyService.svc /d:D:/test

Esto produjo lo siguiente:

Microsoft (R) Service Model Metadata Tool [Microsoft (R) Windows (R) Communication Foundation, Version 4.0.30319.1] Copyright (c) Microsoft Corporation. All rights reserved. Attempting to download metadata from ''https://mydomain.com/MyService.svc'' using WS-Metadata Exchange or DISCO. Error: Cannot import wsdl:portType Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter Error: Schema with target namespace ''http://mynamespace.com//'' could not be found. XPath to Error Source: //wsdl:definitions[@targetNamespace=''http://mynamespace.com//'']/wsdl:portType[@name=''IMyService''] Error: Cannot import wsdl:binding Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on. XPath to wsdl:portType: //wsdl:definitions[@targetNamespace=''http://mynamespace.com//'']/wsdl:portType[@name=''IMyService''] XPath to Error Source: //wsdl:definitions[@targetNamespace=''http://tempuri.org/'']/wsdl:binding[@name=''WSHttpBinding_IMyService''] Error: Cannot import wsdl:port Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on. XPath to wsdl:binding: //wsdl:definitions[@targetNamespace=''http://tempuri.org/'']/wsdl:binding[@name=''WSHttpBinding_IMyService''] XPath to Error Source: //wsdl:definitions[@targetNamespace=''http://tempuri.org/'']/wsdl:service[@name=''MyService'']/wsdl:port[@name=''WSHttpBinding_IMyService''] Generating files... Warning: No code was generated. If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or services or because all contracts/services were discovered to exist in /reference assemblies. Verify that you passed all the metadata documents to the tool. Warning: If you would like to generate data contracts from schemas make sure to use the /dataContractOnly option.

Eso me dejó completamente perplejo. A pesar de que usaba mucho Google y me volvía loco, y reconsideraba una carrera como conductor de un autobús, finalmente consideré por qué funcionaba bien en la caja de desarrollo. ¿Podría ser un problema de configuración de IIS?

Me remoting simultáneamente en los cuadros de desarrollo y en vivo, y en cada uno encendí el Administrador de IIS (ejecutando IIS 7.5). A continuación, revisé cada configuración en cada cuadro, comparando los valores en cada servidor.

Y ahí está el problema: en "Configuración de SSL" para el sitio, asegúrese de que "Requerir SSL" esté marcado y marque el botón de selección de Certificados de cliente para "Aceptar". ¡Problema fijo!



Si recientemente agregó una colección a su proyecto cuando esto comenzó a ocurrir, el problema puede deberse a dos colecciones que tienen el mismo atributo CollectionDataContract :

[CollectionDataContract(Name="AItems", ItemName="A")] public class CollectionA : List<A> { } [CollectionDataContract(Name="AItems", ItemName="A")] // Wrong public class CollectionB : List<B> { }

Solucioné el error pasando por mi proyecto y asegurándome de que cada nombre y atributo de ItemName fuera único:

[CollectionDataContract(Name="AItems", ItemName="A")] public class CollectionA : List<A> { } [CollectionDataContract(Name="BItems", ItemName="B")] // Corrected public class CollectionB : List<B> { }

Luego actualicé la referencia de servicio y todo funcionó de nuevo.


También tuve el problema de referencias de servicio rotas cuando trabajé con referencias de proyecto en ambos lados (el proyecto de servicio y el proyecto tenían una referencia al servicio). Si el .dll del proyecto al que se hace referencia, por ejemplo, se llama "Contoso.Development.Common", pero el nombre del proyecto simplemente se abrevia como "Común", también las referencias del proyecto a este proyecto se denominan simplemente "Común". Sin embargo, el servicio espera una referencia a "Contoso.Development.Common" para resolver clases (si esta opción está activada en las opciones de referencia del servicio).

Entonces, con el explorador, abrí la carpeta del proyecto que hace referencia al servicio y al proyecto "Común". Allí edito el archivo del proyecto VS (.csproj) con el bloc de notas. Busque el nombre del proyecto referido (que es "Common.csproj" en este ejemplo) y encontrará rápidamente la entrada de configuración que representa la referencia del proyecto.

Cambié

<ProjectReference Include="../Common/Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Common</Name> </ProjectReference>

a

<ProjectReference Include="../Common/Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Contoso.Development.Common</Name> </ProjectReference>

Lo importante es cambiar el nombre de la referencia al nombre de la dll que el proyecto al que se hace referencia tiene como salida.

Luego vuelva a cambiar a VS. Allí se le pedirá que vuelva a cargar el proyecto ya que se ha modificado fuera de VS. Haga clic en el botón de recarga.

Después de hacerlo, agregar y actualizar la referencia de servicio funcionó tal como se esperaba.

Espero que esto también ayude a alguien más.

Saludos MH


Tuve este problema con un Silverlight 5 actualizado de una versión anterior.

Incluso volver a agregar la referencia de servicio todavía me daba un Reference.cs vacío

Terminé teniendo que crear un nuevo proyecto y volver a crear la referencia del servicio. Esto es algo que debes probar si has pasado más de media hora en esto. Incluso si está decidido a arreglar el proyecto original, puede probar esto solo para ver qué sucede y luego trabajar hacia atrás para tratar de solucionar el problema.

Nunca supe exactamente cuál era el problema, pero posiblemente algo en el archivo .csproj no se actualizó o se produjo un error.